From c22d70e76fb20be1cf2f9457f565ea9f1b56c0c6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 2 Oct 2007 00:03:53 +0000 Subject: [PATCH] add a few things to mod_fifo git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5776 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/mod/applications/mod_fifo/Makefile | 2 +- src/mod/applications/mod_fifo/mod_fifo.c | 133 +++++++++++++++++++++-- 2 files changed, 122 insertions(+), 13 deletions(-) diff --git a/src/mod/applications/mod_fifo/Makefile b/src/mod/applications/mod_fifo/Makefile index c6d645e6aa..2c35e6e98f 100644 --- a/src/mod/applications/mod_fifo/Makefile +++ b/src/mod/applications/mod_fifo/Makefile @@ -1,2 +1,2 @@ BASE=../../../.. -include /usr/src/freeswitch.trunk/build/modmake.rules +include $(BASE)/build/modmake.rules diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 1a8ed38790..09be423ce9 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -24,8 +24,6 @@ * Contributor(s): * * Anthony Minessale II - * Neal Horman - * * * mod_fifo.c -- FIFO * @@ -36,20 +34,66 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown); SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load); SWITCH_MODULE_DEFINITION(mod_fifo, mod_fifo_load, mod_fifo_shutdown, NULL); + + +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_channel_t *channel; + + bleg = (switch_core_session_t *) buf; + + switch (itype) { + case SWITCH_INPUT_TYPE_DTMF: + { + char *dtmf = (char *) input; + if (*dtmf == '*') { + channel = switch_core_session_get_channel(session); + if (switch_channel_test_flag(channel, CF_ORIGINATOR)) { + channel = switch_core_session_get_channel(bleg); + switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); + return SWITCH_STATUS_BREAK; + } + } + } + break; + default: + break; + } + + return SWITCH_STATUS_SUCCESS; +} + + +#define check_string(s) if (!switch_strlen_zero(s) && !strcasecmp(s, "undef")) { s = NULL; } + + +static switch_status_t read_frame_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data) +{ + switch_queue_t *fifo = (switch_queue_t *) user_data; + if (switch_queue_size(fifo)) { + return SWITCH_STATUS_FALSE; + } + return SWITCH_STATUS_SUCCESS; +} + static struct { switch_hash_t *fifo_hash; switch_memory_pool_t *pool; } globals; #define FIFO_DESC "Fifo for stacking parked calls." -#define FIFO_USAGE " [in | out [nowait]]" +#define FIFO_USAGE " [in [|undef] [|undef] | out [wait|nowait] [|undef] [|undef]]" SWITCH_STANDARD_APP(fifo_function) { int argc; - char *mydata = NULL, *argv[4] = { 0 }; + char *mydata = NULL, *argv[5] = { 0 }; switch_queue_t *fifo; switch_channel_t *channel; int nowait = 0; + char *moh = NULL; + char *announce = NULL; + if (switch_strlen_zero(data)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Args\n"); @@ -70,7 +114,8 @@ SWITCH_STANDARD_APP(fifo_function) } channel = switch_core_session_get_channel(session); - + moh = switch_channel_get_variable(channel, "fifo_music"); + announce = switch_channel_get_variable(channel, "fifo_announce"); if (argc > 2) { nowait = !strcasecmp(argv[2], "nowait"); @@ -78,22 +123,42 @@ SWITCH_STANDARD_APP(fifo_function) if (!strcasecmp(argv[1], "in")) { char *uuid = strdup(switch_core_session_get_uuid(session)); - char *moh = NULL; switch_channel_answer(channel); - moh = switch_channel_get_variable(channel, "fifo_music"); - if (argc > 2) { - moh = argv[2]; + announce = argv[2]; } + if (argc > 3) { + moh = argv[3]; + } + + check_string(announce); + check_string(moh); + + if (moh) { switch_ivr_broadcast(uuid, moh, SMF_LOOP | SMF_ECHO_ALEG); } - + + switch_channel_set_flag(channel, CF_TAGGED); + switch_queue_push(fifo, uuid); switch_ivr_park(session, NULL); + + if (switch_channel_ready(channel)) { + if (announce) { + switch_ivr_play_file(session, NULL, announce, NULL); + } + } + + switch_channel_clear_flag(channel, CF_TAGGED); + + if (switch_channel_ready(channel)) { + switch_channel_set_state(channel, CS_HIBERNATE); + } + return; } else if (!strcasecmp(argv[1], "out")) { void *pop; @@ -102,12 +167,31 @@ SWITCH_STANDARD_APP(fifo_function) char *uuid; int done = 0; switch_core_session_t *other_session; + switch_input_args_t args = { 0 }; + if (argc > 3) { + announce = argv[3]; + } + + if (argc > 4) { + moh = argv[4]; + } + + check_string(announce); + check_string(moh); + if (!nowait) { switch_channel_answer(channel); } + for (;;) { + if (moh) { + args.read_frame_callback = read_frame_callback; + args.user_data = fifo; + switch_ivr_play_file(session, NULL, moh, &args); + } + if (switch_queue_trypop(fifo, &pop) != SWITCH_STATUS_SUCCESS) { if (nowait) { return; @@ -126,13 +210,38 @@ SWITCH_STANDARD_APP(fifo_function) if ((other_session = switch_core_session_locate(uuid))) { switch_channel_t *other_channel = switch_core_session_get_channel(other_session); + switch_caller_profile_t *cloned_profile; + + if (announce) { + switch_ivr_play_file(session, NULL, announce, NULL); + } else { + switch_ivr_sleep(session, 500); + } switch_channel_clear_flag(other_channel, CF_CONTROLLED); switch_channel_clear_flag(other_channel, CF_BROADCAST); switch_channel_set_flag(other_channel, CF_BREAK); switch_core_session_kill_channel(other_session, SWITCH_SIG_BREAK); - switch_ivr_multi_threaded_bridge(session, other_session, NULL, NULL, NULL); + while (switch_channel_test_flag(other_channel, CF_TAGGED)) { + status = switch_core_session_read_frame(session, &read_frame, -1, 0); + if (!SWITCH_READ_ACCEPTABLE(status)) { + break; + } + } + + switch_channel_answer(channel); + cloned_profile = switch_caller_profile_clone(session, switch_channel_get_caller_profile(channel)); + assert(cloned_profile); + switch_channel_set_originator_caller_profile(other_channel, cloned_profile); + + cloned_profile = switch_caller_profile_clone(other_session, switch_channel_get_caller_profile(channel)); + assert(cloned_profile); + switch_channel_set_originatee_caller_profile(channel, cloned_profile); + + switch_ivr_multi_threaded_bridge(session, other_session, on_dtmf, other_session, session); switch_core_session_rwunlock(other_session); - done = 1; + if (nowait) { + done = 1; + } } switch_safe_free(uuid);