From 2a90a43fd46e240b0a99ba6aa19c1f061b8e8bad Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 31 Dec 2008 01:08:51 +0000 Subject: [PATCH] a few changes git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11011 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_ivr.h | 2 +- src/include/switch_types.h | 3 +- .../mod_conference/mod_conference.c | 33 +++++++++++++++---- .../applications/mod_dptools/mod_dptools.c | 22 ++++++++++++- src/mod/endpoints/mod_sofia/mod_sofia.c | 6 ++++ src/switch_core_io.c | 9 +++-- src/switch_ivr_async.c | 27 +++++++++++++-- src/switch_ivr_bridge.c | 2 +- 8 files changed, 88 insertions(+), 16 deletions(-) diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 6cfb7dc5a0..058e5a1b57 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -780,7 +780,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_parser_set_terminator(sw SWITCH_DECLARE(switch_status_t) switch_ivr_bind_dtmf_meta_session(switch_core_session_t *session, uint32_t key, switch_bind_flag_t bind_flags, 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_unbind_dtmf_meta_session(switch_core_session_t *session, uint32_t key); 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_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session, const char *tosay, const char *module_name, const char *say_type, const char *say_method, switch_input_args_t *args); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index fd2b6c37ed..c08f926faf 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -179,7 +179,8 @@ typedef enum { SBF_DIAL_BLEG = (1 << 2), SBF_EXEC_BLEG = (1 << 3), SBF_EXEC_OPPOSITE = (1 << 4), - SBF_EXEC_SAME = (1 << 5) + SBF_EXEC_SAME = (1 << 5), + SBF_ONCE = (1 << 6) } switch_bind_flag_enum_t; typedef uint32_t switch_bind_flag_t; diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 89c68e3033..d09fe451c0 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1790,8 +1790,9 @@ static void conference_loop_output(conference_member_t *member) const char *toval = switch_channel_get_variable(channel, "conference_auto_outcall_timeout"); const char *flags = switch_channel_get_variable(channel, "conference_auto_outcall_flags"); const char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce"); + const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix"); int to = 60; - + if (ann) { member->conference->special_announce = switch_core_strdup(member->conference->pool, ann); } @@ -1806,7 +1807,20 @@ static void conference_loop_output(conference_member_t *member) } for (cp = call_list; cp; cp = cp->next) { - conference_outcall_bg(member->conference, NULL, NULL, cp->string, to, switch_str_nil(flags), cid_name, cid_num); + int argc; + char *argv[512] = { 0 }; + char *cpstr = strdup(cp->string); + int x = 0; + + switch_assert(cpstr); + argc = switch_separate_string(cpstr, ',', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]); + switch_assert(dial_str); + conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num); + switch_safe_free(dial_str); + } + switch_safe_free(cpstr); } } /* Fair WARNING, If you expect the caller to hear anything or for digit handling to be processed, */ @@ -3881,7 +3895,7 @@ static switch_status_t conference_outcall(conference_obj_t *conference, goto done; } /* add them to the conference */ - if (flags && !strcasecmp(flags, "none")) { + if (flags && strcasecmp(flags, "none")) { switch_snprintf(appdata, sizeof(appdata), "%s+flags{%s}", conference_name, flags); switch_caller_extension_add_application(peer_session, extension, (char *) global_app_name, appdata); } else { @@ -4059,15 +4073,20 @@ static void set_mflags(char *flags, member_flag_t *f) if (flags) { if (strstr(flags, "mute")) { *f &= ~MFLAG_CAN_SPEAK; - } else if (strstr(flags, "deaf")) { + } + + if (strstr(flags, "deaf")) { *f &= ~MFLAG_CAN_HEAR; - } else if (strstr(flags, "waste")) { + } + + if (strstr(flags, "waste")) { *f |= MFLAG_WASTE_BANDWIDTH; - } else if (strstr(flags, "endconf")) { + } + + if (strstr(flags, "endconf")) { *f |= MFLAG_ENDCONF; } } - } static void clear_eflags(char *events, uint32_t *f) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 958c79b6dc..6c6873ba1a 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -148,7 +148,21 @@ SWITCH_STANDARD_APP(soft_hold_function) } } -#define BIND_SYNTAX " [a|b|ab] [a|b|o|s] " +#define UNBIND_SYNTAX "[]" +SWITCH_STANDARD_APP(dtmf_unbind_function) +{ + char *key = (char *) data; + int kval = 0; + + if (key) { + kval = atoi(key); + } + + switch_ivr_unbind_dtmf_meta_session(session, kval); + +} + +#define BIND_SYNTAX " [a|b|ab] [a|b|o|s|1] " SWITCH_STANDARD_APP(dtmf_bind_function) { char *argv[4] = { 0 }; @@ -208,6 +222,10 @@ SWITCH_STANDARD_APP(dtmf_bind_function) } } + if (strchr(argv[2], '1')) { + bind_flags |= SBF_ONCE; + } + if (switch_ivr_bind_dtmf_meta_session(session, kval, bind_flags, argv[3]) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bind Error!\n"); } @@ -2514,6 +2532,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) 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, "unbind_meta_app", "Unbind a key from an application", "Unbind a key from an application", dtmf_unbind_function, + UNBIND_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); 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); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index e05de90c3d..f1d4332530 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -2316,6 +2316,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session private_object_t *tech_pvt = NULL; switch_channel_t *nchannel; char *host = NULL, *dest_to = NULL; + const char *hval = NULL; *new_session = NULL; @@ -2520,6 +2521,11 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session *new_session = nsession; cause = SWITCH_CAUSE_SUCCESS; + if ((hval = switch_event_get_header(var_event, "sip_auto_answer")) && switch_true(hval)) { + switch_channel_set_variable_printf(nchannel, "sip_h_Call-Info", ";answer-after=0", profile->sipip); + switch_channel_set_variable(nchannel, "sip_invite_params", "intercom=true"); + } + if (session) { switch_channel_t *o_channel = switch_core_session_get_channel(session); diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 2607874618..b364ea1b94 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -571,7 +571,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess switch_status_t status = SWITCH_STATUS_FALSE; switch_frame_t *enc_frame = NULL, *write_frame = frame; - unsigned int flag = 0, need_codec = 0, perfect = 0, do_bugs = 0, do_write = 0, do_resample = 0, ptime_mismatch = 0, pass_cng = 0; + unsigned int flag = 0, need_codec = 0, perfect = 0, do_bugs = 0, do_write = 0, do_resample = 0, ptime_mismatch = 0, pass_cng = 0, resample = 0; switch_assert(session != NULL); switch_assert(frame != NULL); @@ -675,6 +675,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess switch (status) { case SWITCH_STATUS_RESAMPLE: + resample++; write_frame = &session->raw_write_frame; if (!session->write_resampler) { switch_mutex_lock(session->resample_mutex); @@ -843,6 +844,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess switch (status) { case SWITCH_STATUS_RESAMPLE: + resample++; /* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Fixme 2\n"); */ case SWITCH_STATUS_SUCCESS: session->enc_write_frame.codec = session->write_codec; @@ -917,6 +919,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag); switch (status) { case SWITCH_STATUS_RESAMPLE: + resample++; session->enc_write_frame.codec = session->write_codec; session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t); session->enc_write_frame.m = frame->m; @@ -993,7 +996,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess switch_set_flag(write_frame, SFF_CNG); } - if (ptime_mismatch) { + if (ptime_mismatch || resample) { write_frame->timestamp = 0; } @@ -1009,7 +1012,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess done: - if (ptime_mismatch) { + if (ptime_mismatch || resample) { write_frame->timestamp = 0; } diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 4ce56e4193..afcf51b421 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1521,6 +1521,13 @@ static switch_status_t meta_on_dtmf(switch_core_session_t *session, const switch switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Processing meta digit '%c' [%s]\n", switch_channel_get_name(channel), dtmf->digit, md->sr[direction].map[dval].app); switch_ivr_broadcast(switch_core_session_get_uuid(session), md->sr[direction].map[dval].app, flags); + + if ((md->sr[direction].map[dval].bind_flags & SBF_ONCE)) { + memset(&md->sr[direction].map[dval], 0, sizeof(md->sr[direction].map[dval])); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Unbinding meta digit '%c'\n", + switch_channel_get_name(channel), dtmf->digit); + } + } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s Ignoring meta digit '%c' not mapped\n", switch_channel_get_name(channel), dtmf->digit); @@ -1534,10 +1541,26 @@ static switch_status_t meta_on_dtmf(switch_core_session_t *session, const switch return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(switch_status_t) switch_ivr_unbind_dtmf_meta_session(switch_core_session_t *session) +SWITCH_DECLARE(switch_status_t) switch_ivr_unbind_dtmf_meta_session(switch_core_session_t *session, uint32_t key) { switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_set_private(channel, SWITCH_META_VAR_KEY, NULL); + + if (key) { + dtmf_meta_data_t *md = switch_channel_get_private(channel, SWITCH_META_VAR_KEY); + + if (!md || key > 9) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid key %u\n", key); + return SWITCH_STATUS_FALSE; + } + + memset(&md->sr[SWITCH_DTMF_RECV].map[key], 0, sizeof(md->sr[SWITCH_DTMF_RECV].map[key])); + memset(&md->sr[SWITCH_DTMF_SEND].map[key], 0, sizeof(md->sr[SWITCH_DTMF_SEND].map[key])); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "UnBound A-Leg: %d\n", key); + + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "UnBound A-Leg: ALL\n"); + switch_channel_set_private(channel, SWITCH_META_VAR_KEY, NULL); + } return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 566b2a1883..9c08dcc7a2 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1187,7 +1187,7 @@ SWITCH_DECLARE(void) switch_ivr_intercept_session(switch_core_session_t *session switch_channel_answer(rchannel); } - switch_channel_set_state_flag(rchannel, CF_TRANSFER); + switch_channel_set_state_flag(rchannel, CF_TRANSFER); switch_channel_set_state(rchannel, CS_PARK); if (bchannel) {