allow recursive broadcasting

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15757 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-12-02 18:13:11 +00:00
parent 262da8b6a0
commit 5e1914efca
5 changed files with 78 additions and 42 deletions

View File

@ -826,11 +826,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_exec(_In_ switch_core_sessio
\param session the current session \param session the current session
\param app the application's name \param app the application's name
\param arg application arguments \param arg application arguments
\warning Has to be called from the session's thread \param flags pointer to a flags variable to set the applications flags to
\return the application's return value \return the application's return value
*/ */
SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application(_In_ switch_core_session_t *session, SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flags(_In_ switch_core_session_t *session,
_In_ const char *app, _In_opt_z_ const char *arg); _In_ const char *app, _In_opt_z_ const char *arg, _Out_ int32_t *flags);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_app_flags(const char *app, int32_t *flags);
/*!
\brief Execute an application on a session
\param session the current session
\param app the application's name
\param arg application arguments
\return the application's return value
*/
#define switch_core_session_execute_application(_a, _b, _c) switch_core_session_execute_application_get_flags(_a, _b, _c, NULL)
/*! /*!
\brief Run a dialplan and execute an extension \brief Run a dialplan and execute an extension
\param session the current session \param session the current session

View File

@ -943,6 +943,7 @@ typedef enum {
CF_MEDIA_BRIDGE_TTL, CF_MEDIA_BRIDGE_TTL,
CF_BYPASS_MEDIA_AFTER_BRIDGE, CF_BYPASS_MEDIA_AFTER_BRIDGE,
CF_LEG_HOLDING, CF_LEG_HOLDING,
CF_BROADCAST_DROP_MEDIA,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
CF_FLAG_MAX CF_FLAG_MAX
} switch_channel_flag_t; } switch_channel_flag_t;
@ -983,7 +984,8 @@ typedef uint32_t switch_frame_flag_t;
typedef enum { typedef enum {
SAF_NONE = 0, SAF_NONE = 0,
SAF_SUPPORT_NOMEDIA = (1 << 0), SAF_SUPPORT_NOMEDIA = (1 << 0),
SAF_ROUTING_EXEC = (1 << 1) SAF_ROUTING_EXEC = (1 << 1),
SAF_MEDIA_TAP = (1 << 2)
} switch_application_flag_enum_t; } switch_application_flag_enum_t;
typedef uint32_t switch_application_flag_t; typedef uint32_t switch_application_flag_t;

View File

@ -2999,18 +2999,18 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "unbind_meta_app", "Unbind a key from an application", "Unbind a key from an application", dtmf_unbind_function, SWITCH_ADD_APP(app_interface, "unbind_meta_app", "Unbind a key from an application", "Unbind a key from an application", dtmf_unbind_function,
UNBIND_SYNTAX, SAF_SUPPORT_NOMEDIA); UNBIND_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "intercept", "intercept", "intercept", intercept_function, INTERCEPT_SYNTAX, SAF_NONE); 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); SWITCH_ADD_APP(app_interface, "eavesdrop", "eavesdrop on a uuid", "eavesdrop on a uuid", eavesdrop_function, eavesdrop_SYNTAX, SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "three_way", "three way call with a uuid", "three way call with a uuid", three_way_function, threeway_SYNTAX, SAF_NONE); SWITCH_ADD_APP(app_interface, "three_way", "three way call with a uuid", "three way call with a uuid", three_way_function, threeway_SYNTAX, SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "set_user", "Set a User", "Set a User", set_user_function, SET_USER_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC ); SWITCH_ADD_APP(app_interface, "set_user", "Set a User", "Set a User", set_user_function, SET_USER_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC );
SWITCH_ADD_APP(app_interface, "stop_dtmf", "stop inband dtmf", "Stop detecting inband dtmf.", stop_dtmf_session_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "stop_dtmf", "stop inband dtmf", "Stop detecting inband dtmf.", stop_dtmf_session_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "start_dtmf", "Detect dtmf", "Detect inband dtmf on the session", dtmf_session_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "start_dtmf", "Detect dtmf", "Detect inband dtmf on the session", dtmf_session_function, "", SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "stop_dtmf_generate", "stop inband dtmf generation", "Stop generating inband dtmf.", SWITCH_ADD_APP(app_interface, "stop_dtmf_generate", "stop inband dtmf generation", "Stop generating inband dtmf.",
stop_dtmf_session_generate_function, "[write]", SAF_NONE); stop_dtmf_session_generate_function, "[write]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "start_dtmf_generate", "Generate dtmf", "Generate inband dtmf on the session", dtmf_session_generate_function, "", SWITCH_ADD_APP(app_interface, "start_dtmf_generate", "Generate dtmf", "Generate inband dtmf on the session", dtmf_session_generate_function, "",
SAF_NONE); SAF_NONE);
SWITCH_ADD_APP(app_interface, "stop_tone_detect", "stop detecting tones", "Stop detecting tones", stop_fax_detect_session_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "stop_tone_detect", "stop detecting tones", "Stop detecting tones", stop_fax_detect_session_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "fax_detect", "Detect faxes", "Detect fax send tone", fax_detect_session_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "fax_detect", "Detect faxes", "Detect fax send tone", fax_detect_session_function, "", SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "tone_detect", "Detect tones", "Detect tones", tone_detect_session_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "tone_detect", "Detect tones", "Detect tones", tone_detect_session_function, "", SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "echo", "Echo", "Perform an echo test against the calling channel", echo_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "echo", "Echo", "Perform an echo test against the calling channel", echo_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "park", "Park", "Park", park_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "park", "Park", "Park", park_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "park_state", "Park State", "Park State", park_state_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "park_state", "Park State", "Park State", park_state_function, "", SAF_NONE);
@ -3023,14 +3023,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "play_and_get_digits", "Play and get Digits", "Play and get Digits", SWITCH_ADD_APP(app_interface, "play_and_get_digits", "Play and get Digits", "Play and get Digits",
play_and_get_digits_function, "<min> <max> <tries> <timeout> <terminators> <file> <invalid_file> <var_name> <regexp>", SAF_NONE); play_and_get_digits_function, "<min> <max> <tries> <timeout> <terminators> <file> <invalid_file> <var_name> <regexp>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "stop_record_session", "Stop Record Session", STOP_SESS_REC_DESC, stop_record_session_function, "<path>", SAF_NONE); SWITCH_ADD_APP(app_interface, "stop_record_session", "Stop Record Session", STOP_SESS_REC_DESC, stop_record_session_function, "<path>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "record_session", "Record Session", SESS_REC_DESC, record_session_function, "<path> [+<timeout>]", SAF_NONE); SWITCH_ADD_APP(app_interface, "record_session", "Record Session", SESS_REC_DESC, record_session_function, "<path> [+<timeout>]", SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "record", "Record File", "Record a file from the channels input", record_function, SWITCH_ADD_APP(app_interface, "record", "Record File", "Record a file from the channels input", record_function,
"<path> [<time_limit_secs>] [<silence_thresh>] [<silence_hits>]", SAF_NONE); "<path> [<time_limit_secs>] [<silence_thresh>] [<silence_hits>]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "preprocess", "pre-process", "pre-process", preprocess_session_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "preprocess", "pre-process", "pre-process", preprocess_session_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "stop_displace_session", "Stop Displace File", "Stop Displacing to a file", stop_displace_session_function, "<path>", SWITCH_ADD_APP(app_interface, "stop_displace_session", "Stop Displace File", "Stop Displacing to a file", stop_displace_session_function, "<path>",
SAF_NONE); SAF_NONE);
SWITCH_ADD_APP(app_interface, "displace_session", "Displace File", DISPLACE_DESC, displace_session_function, "<path> [<flags>] [+time_limit_ms]", SWITCH_ADD_APP(app_interface, "displace_session", "Displace File", DISPLACE_DESC, displace_session_function, "<path> [<flags>] [+time_limit_ms]",
SAF_NONE); SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "speak", "Speak text", SPEAK_DESC, speak_function, "<engine>|<voice>|<text>", SAF_NONE); SWITCH_ADD_APP(app_interface, "speak", "Speak text", SPEAK_DESC, speak_function, "<engine>|<voice>|<text>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "clear_speech_cache", "Clear Speech Handle Cache", "Clear Speech Handle Cache", clear_speech_cache_function, "", SWITCH_ADD_APP(app_interface, "clear_speech_cache", "Clear Speech Handle Cache", "Clear Speech Handle Cache", clear_speech_cache_function, "",
SAF_NONE); SAF_NONE);

View File

@ -865,15 +865,27 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_queue_private_event(switch_c
return status; return status;
} }
#define check_media(session) \
{ \
if (switch_channel_test_flag(session->channel, CF_BROADCAST_DROP_MEDIA)) { \
switch_channel_clear_flag(session->channel, CF_BROADCAST_DROP_MEDIA); \
switch_ivr_nomedia(session->uuid_str, SMF_REBRIDGE); \
} \
} \
SWITCH_DECLARE(uint32_t) switch_core_session_private_event_count(switch_core_session_t *session) SWITCH_DECLARE(uint32_t) switch_core_session_private_event_count(switch_core_session_t *session)
{ {
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
uint32_t count = 0;
if (!switch_channel_test_flag(channel, CF_EVENT_LOCK) && session->private_event_queue) { if (!switch_channel_test_flag(channel, CF_EVENT_LOCK) && session->private_event_queue) {
return switch_queue_size(session->private_event_queue); count = switch_queue_size(session->private_event_queue);
if (count == 0) {
check_media(session);
}
} }
return 0; return count;
} }
SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_private_event(switch_core_session_t *session, switch_event_t **event) SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_private_event(switch_core_session_t *session, switch_event_t **event)
@ -889,6 +901,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_private_event(switch
if (session->private_event_queue) { if (session->private_event_queue) {
if ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue, &pop)) == SWITCH_STATUS_SUCCESS) { if ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
*event = (switch_event_t *) pop; *event = (switch_event_t *) pop;
} else {
check_media(session);
} }
} }
@ -905,6 +919,7 @@ SWITCH_DECLARE(uint32_t) switch_core_session_flush_private_events(switch_core_se
while ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue, &pop)) == SWITCH_STATUS_SUCCESS) { while ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
x++; x++;
} }
check_media(session);
} }
return x; return x;
@ -1420,7 +1435,28 @@ SWITCH_DECLARE(switch_app_log_t *) switch_core_session_get_app_log(switch_core_s
return session->app_log; return session->app_log;
} }
SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application(switch_core_session_t *session, const char *app, const char *arg) SWITCH_DECLARE(switch_status_t) switch_core_session_get_app_flags(const char *app, int32_t *flags)
{
switch_application_interface_t *application_interface;
switch_status_t status = SWITCH_STATUS_FALSE;
switch_assert(flags);
*flags = 0;
if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Application %s\n", app);
} else if (application_interface->flags) {
*flags = application_interface->flags;
status = SWITCH_STATUS_SUCCESS;
}
return status;
}
SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flags(switch_core_session_t *session, const char *app,
const char *arg, int32_t *flags)
{ {
switch_application_interface_t *application_interface; switch_application_interface_t *application_interface;
switch_status_t status = SWITCH_STATUS_SUCCESS; switch_status_t status = SWITCH_STATUS_SUCCESS;
@ -1442,6 +1478,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application(switch_c
switch_goto_status(SWITCH_STATUS_FALSE, done); switch_goto_status(SWITCH_STATUS_FALSE, done);
} }
if (flags && application_interface->flags) {
*flags = application_interface->flags;
}
if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) { if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) {
switch_ivr_media(session->uuid_str, SMF_NONE); switch_ivr_media(session->uuid_str, SMF_NONE);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Application %s Requires media on channel %s!\n", switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Application %s Requires media on channel %s!\n",

View File

@ -2662,7 +2662,6 @@ SWITCH_DECLARE(uint32_t) switch_ivr_schedule_broadcast(time_t runtime, const cha
SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags) SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags)
{ {
switch_channel_t *channel; switch_channel_t *channel;
int nomedia;
switch_core_session_t *session, *master; switch_core_session_t *session, *master;
switch_event_t *event; switch_event_t *event;
switch_core_session_t *other_session = NULL; switch_core_session_t *other_session = NULL;
@ -2671,7 +2670,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha
char *cause = NULL; char *cause = NULL;
char *mypath; char *mypath;
char *p; char *p;
int custom = 0; int app_flags = 0, nomedia = 1;
switch_assert(path); switch_assert(path);
@ -2689,19 +2688,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha
*p++ = '\0'; *p++ = '\0';
*p++ = '\0'; *p++ = '\0';
path = p; path = p;
custom++;
} }
if (!custom && (switch_channel_test_flag(channel, CF_EVENT_PARSE))) { if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Channel [%s][%s] already broadcasting...broadcast aborted\n", nomedia = 1;
switch_channel_get_name(channel), path);
switch_core_session_rwunlock(session);
switch_safe_free(mypath);
return SWITCH_STATUS_FALSE;
}
if ((nomedia = switch_channel_test_flag(channel, CF_PROXY_MODE))) {
switch_ivr_media(uuid, SMF_REBRIDGE); switch_ivr_media(uuid, SMF_REBRIDGE);
} }
@ -2715,9 +2705,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha
if ((flags & SMF_ECHO_BLEG) && (other_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) if ((flags & SMF_ECHO_BLEG) && (other_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
&& (other_session = switch_core_session_locate(other_uuid))) { && (other_session = switch_core_session_locate(other_uuid))) {
if ((flags & SMF_EXEC_INLINE)) { if ((flags & SMF_EXEC_INLINE)) {
switch_core_session_execute_application(other_session, app, path); switch_core_session_execute_application_get_flags(other_session, app, path, &app_flags);
nomedia = 0; nomedia = 0;
} else { } else {
switch_core_session_get_app_flags(app, &app_flags);
if (switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { if (switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", app); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", app);
@ -2735,21 +2726,20 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha
switch_core_session_queue_private_event(other_session, &event); switch_core_session_queue_private_event(other_session, &event);
} }
} }
switch_core_session_rwunlock(other_session); switch_core_session_rwunlock(other_session);
master = other_session; master = other_session;
other_session = NULL; other_session = NULL;
} }
if (switch_stristr("record", app)) { if ((app_flags & SAF_MEDIA_TAP)) {
nomedia = 0; nomedia = 0;
} }
if ((flags & SMF_ECHO_ALEG)) { if ((flags & SMF_ECHO_ALEG)) {
if ((flags & SMF_EXEC_INLINE)) { if ((flags & SMF_EXEC_INLINE)) {
switch_core_session_execute_application(session, app, path);
nomedia = 0; nomedia = 0;
switch_core_session_execute_application(session, app, path);
} else { } else {
if (switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { if (switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute");
@ -2764,20 +2754,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hold-bleg", "true"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hold-bleg", "true");
} }
switch_core_session_queue_private_event(session, &event); switch_core_session_queue_private_event(session, &event);
if (nomedia) switch_channel_set_flag(channel, CF_BROADCAST_DROP_MEDIA);
} }
} }
master = session; master = session;
} }
if (nomedia) {
if (switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "nomedia");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "nomedia-uuid", uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event-lock", "true");
switch_core_session_queue_private_event(master, &event);
}
}
if (cause) { if (cause) {
if (switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { if (switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute");