[commit] r7885 - in freeswitch/trunk/src: . include mod/applications/mod_commands mod/applications/mod_dptools
Author: anthm Date: Wed Mar 12 21:08:42 2008 New Revision: 7885 Modified: freeswitch/trunk/src/include/switch_types.h freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c freeswitch/trunk/src/switch_core_state_machine.c freeswitch/trunk/src/switch_ivr.c freeswitch/trunk/src/switch_ivr_async.c freeswitch/trunk/src/switch_ivr_bridge.c freeswitch/trunk/src/switch_ivr_originate.c freeswitch/trunk/src/switch_ivr_play_say.c freeswitch/trunk/src/switch_rtp.c Log: the same guy who added att xfer to asterisk was nice enough to add it to freeswitch too Modified: freeswitch/trunk/src/include/switch_types.h ============================================================================== --- freeswitch/trunk/src/include/switch_types.h (original) +++ freeswitch/trunk/src/include/switch_types.h Wed Mar 12 21:08:42 2008 @@ -102,6 +102,9 @@ #define SWITCH_PATH_SEPARATOR "/" #endif #define SWITCH_URL_SEPARATOR "://" +#define SWITCH_CALL_TIMEOUT_VARIABLE "call_timeout" +#define SWITCH_HOLDING_UUID_VARIABLE "holding_uuid" +#define SWITCH_API_BRIDGE_END_VARIABLE "api_after_bridge" #define SWITCH_API_HANGUP_HOOK_VARIABLE "api_hangup_hook" #define SWITCH_PROCESS_CDR_VARIABLE "process_cdr" #define SWITCH_BRIDGE_CHANNEL_VARIABLE "bridge_channel" @@ -564,7 +567,8 @@ SWITCH_STATUS_MORE_DATA, SWITCH_STATUS_NOTFOUND, SWITCH_STATUS_UNLOAD, - SWITCH_STATUS_NOUNLOAD + SWITCH_STATUS_NOUNLOAD, + SWITCH_STATUS_IGNORE } switch_status_t; @@ -717,7 +721,8 @@ CF_RESET = (1 << 24), CF_ORIGINATING = (1 << 25), CF_STOP_BROADCAST = (1 << 26), - CF_PROXY_MEDIA = (1 << 27) + CF_PROXY_MEDIA = (1 << 27), + CF_INNER_BRIDGE = (1 << 28) } switch_channel_flag_t; Modified: freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c ============================================================================== --- freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c (original) +++ freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c Wed Mar 12 21:08:42 2008 @@ -1172,10 +1172,25 @@ argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); } - if (switch_strlen_zero(cmd) || argc != 2) { + if (switch_strlen_zero(cmd) || argc < 2) { stream->write_function(stream, "-USAGE: %s\n", UUID_SYNTAX); } else { - if (switch_ivr_uuid_bridge(argv[0], argv[1]) != SWITCH_STATUS_SUCCESS) { + switch_status_t status; + char *who = NULL; + + if ((status = switch_ivr_uuid_bridge(argv[0], argv[1])) != SWITCH_STATUS_SUCCESS) { + if (argv[2]) { + if ((status = switch_ivr_uuid_bridge(argv[0], argv[2])) == SWITCH_STATUS_SUCCESS) { + who = argv[2]; + } + } + } else { + who = argv[1]; + } + + if (status == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "+OK %s\n", who); + } else { stream->write_function(stream, "-ERR Invalid uuid\n"); } } 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 Mar 12 21:08:42 2008 @@ -222,6 +222,8 @@ switch_ivr_session_transfer(b_session, argv[1], argv[2], argv[3]); switch_core_session_rwunlock(b_session); } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No B-leg present.\n"); } if (both) { switch_ivr_session_transfer(session, argv[1], argv[2], argv[3]); @@ -1109,6 +1111,146 @@ switch_ivr_speak_text(session, engine, voice, text, &args); } +static switch_status_t xfer_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) +{ + switch_core_session_t *peer_session = (switch_core_session_t *) buf; + + if (!buf || !peer_session) { + return SWITCH_STATUS_SUCCESS; + } + + switch (itype) { + case SWITCH_INPUT_TYPE_DTMF: + { + switch_dtmf_t *dtmf = (switch_dtmf_t *) input; + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); + + if (dtmf->digit == '#') { + return SWITCH_STATUS_FALSE; + } + + if (dtmf->digit == '0') { + switch_caller_extension_t *extension = NULL; + const char *app = "three_way"; + const char *app_arg = switch_core_session_get_uuid(session); + const char *holding = switch_channel_get_variable(channel, SWITCH_HOLDING_UUID_VARIABLE); + switch_core_session_t *b_session; + + if (holding && (b_session = switch_core_session_locate(holding))) { + switch_channel_t *b_channel = switch_core_session_get_channel(b_session); + if (!switch_channel_ready(b_channel)) { + app = "intercept"; + } + switch_core_session_rwunlock(b_session); + } + + if ((extension = switch_caller_extension_new(peer_session, app, app_arg)) == 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "memory error!\n"); + abort(); + } + + switch_caller_extension_add_application(peer_session, extension, app, app_arg); + switch_channel_set_caller_extension(peer_channel, extension); + switch_channel_set_flag(peer_channel, CF_TRANSFER); + switch_channel_set_state(peer_channel, CS_EXECUTE); + + return SWITCH_STATUS_FALSE; + } + + } + break; + default: + break; + } + + return SWITCH_STATUS_SUCCESS; + + +} + +static switch_status_t hanguphook(switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_channel_state_t state = switch_channel_get_state(channel); + const char *id = NULL; + + if (state == CS_HANGUP || state == CS_RING) { + if ((id = switch_channel_get_variable(channel, "xfer_uuids"))) { + switch_stream_handle_t stream = { 0 }; + SWITCH_STANDARD_STREAM(stream); + switch_api_execute("uuid_bridge", id, NULL, &stream); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\nHangup Command uuid_bridge(%s):\n%s\n", id, switch_str_nil((char *) stream.data)); + switch_safe_free(stream.data); + } + + switch_core_event_hook_remove_state_change(session, hanguphook); + } + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_STANDARD_APP(att_xfer_function) +{ + const char *var; + switch_core_session_t *peer_session = NULL; + switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; + switch_channel_t *channel, *peer_channel = NULL; + const char *bond = NULL; + int timelimit = 60; + + channel = switch_core_session_get_channel(session); + + if ((bond = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) { + bond = switch_core_session_strdup(session, bond); + } + + switch_channel_set_variable(channel, SWITCH_HOLDING_UUID_VARIABLE, bond); + + + if ((var = switch_channel_get_variable(channel, SWITCH_CALL_TIMEOUT_VARIABLE))) { + timelimit = atoi(var); + } + + if (switch_ivr_originate(session, &peer_session, &cause, data, timelimit, NULL, NULL, NULL, NULL, SOF_NONE) != SWITCH_STATUS_SUCCESS) { + return; + } + + peer_channel = switch_core_session_get_channel(peer_session); + switch_channel_set_flag(peer_channel, CF_INNER_BRIDGE); + switch_channel_set_flag(channel, CF_INNER_BRIDGE); + + switch_ivr_multi_threaded_bridge(session, peer_session, xfer_on_dtmf, peer_session, NULL); + + if (bond) { + switch_core_session_t *b_session; + char buf[128] = ""; + + if ((b_session = switch_core_session_locate(bond))) { + switch_channel_t *b_channel = switch_core_session_get_channel(b_session); + switch_snprintf(buf, sizeof(buf), "%s %s", switch_core_session_get_uuid(peer_session), switch_core_session_get_uuid(session)); + switch_channel_set_variable(b_channel, "xfer_uuids", buf); + + switch_snprintf(buf, sizeof(buf), "%s %s", switch_core_session_get_uuid(peer_session), bond); + switch_channel_set_variable(channel, "xfer_uuids", buf); + + switch_core_event_hook_add_state_change(session, hanguphook); + switch_core_event_hook_add_state_change(b_session, hanguphook); + + switch_core_session_rwunlock(b_session); + } + + switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond); + } + + if (peer_session) { + switch_core_session_rwunlock(peer_session); + } + + switch_channel_set_variable(channel, SWITCH_HOLDING_UUID_VARIABLE, NULL); + +} + + SWITCH_STANDARD_APP(read_function) { @@ -1126,7 +1268,7 @@ if (!switch_strlen_zero(data) && (mydata = switch_core_session_strdup(session, data))) { argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No file specified.\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No arguements specified.\n"); return; } @@ -1347,7 +1489,7 @@ return; } - if ((var = switch_channel_get_variable(caller_channel, "call_timeout"))) { + if ((var = switch_channel_get_variable(caller_channel, SWITCH_CALL_TIMEOUT_VARIABLE))) { timelimit = atoi(var); } @@ -1516,13 +1658,13 @@ if (session) { channel = switch_core_session_get_channel(session); - if ((var = switch_channel_get_variable(channel, "call_timeout"))) { + if ((var = switch_channel_get_variable(channel, SWITCH_CALL_TIMEOUT_VARIABLE))) { timelimit = atoi(var); } switch_channel_set_variable(channel, "dialed_user", user); switch_channel_set_variable(channel, "dialed_domain", domain); - + d_dest = switch_channel_expand_variables(channel, dest); } else { @@ -1650,7 +1792,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, "bind_meta_app", "Bind a key to an application", "Bind a key to an application", dtmf_bind_function, BIND_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); SWITCH_ADD_APP(app_interface, "three_way", "three way call with a uuid", "three way call with a uuid", three_way_function, eavesdrop_SYNTAX, SAF_NONE); @@ -1668,6 +1810,7 @@ SWITCH_ADD_APP(app_interface, "park_state", "Park State", "Park State", park_state_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "gentones", "Generate Tones", "Generate tones to the channel", gentones_function, "<tgml_script>[|<loops>]", SAF_NONE); SWITCH_ADD_APP(app_interface, "playback", "Playback File", "Playback a file to the channel", playback_function, "<path>", SAF_NONE); + SWITCH_ADD_APP(app_interface, "att_xfer", "Read Digits", "Read Digits", att_xfer_function, "foo>", SAF_NONE); SWITCH_ADD_APP(app_interface, "read", "Read Digits", "Read Digits", read_function, "<min> <max> <file> <var name> <timeout> <terminators>", 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>", SAF_NONE); Modified: freeswitch/trunk/src/switch_core_state_machine.c ============================================================================== --- freeswitch/trunk/src/switch_core_state_machine.c (original) +++ freeswitch/trunk/src/switch_core_state_machine.c Wed Mar 12 21:08:42 2008 @@ -412,7 +412,7 @@ case CS_HANGUP: /* Deactivate and end the thread */ { const char *var = switch_channel_get_variable(session->channel, SWITCH_PROCESS_CDR_VARIABLE); - const char *hook_var = switch_channel_get_variable(session->channel, SWITCH_API_HANGUP_HOOK_VARIABLE); + const char *hook_var; if (!switch_strlen_zero(var)) { if (!strcasecmp(var, "a_only")) { @@ -431,6 +431,8 @@ STATE_MACRO(hangup, "HANGUP"); switch_core_session_signal_unlock(session); + hook_var = switch_channel_get_variable(session->channel, SWITCH_API_HANGUP_HOOK_VARIABLE); + if (!switch_strlen_zero(hook_var)) { switch_stream_handle_t stream = { 0 }; char *cmd = switch_core_session_strdup(session, hook_var); @@ -439,7 +441,7 @@ *arg++ = '\0'; } SWITCH_STANDARD_STREAM(stream); - switch_api_execute(cmd, arg, session, &stream); + switch_api_execute(cmd, arg, NULL, &stream); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Hangup Command %s(%s):\n%s\n", cmd, arg, switch_str_nil((char *) stream.data)); switch_safe_free(stream.data); } Modified: freeswitch/trunk/src/switch_ivr.c ============================================================================== --- freeswitch/trunk/src/switch_ivr.c (original) +++ freeswitch/trunk/src/switch_ivr.c Wed Mar 12 21:08:42 2008 @@ -310,6 +310,7 @@ if (hold_bleg && switch_true(hold_bleg)) { if ((b_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) { const char *stream; + b_uuid = switch_core_session_strdup(session, b_uuid); if (!(stream = switch_channel_get_variable_partner(channel, SWITCH_HOLD_MUSIC_VARIABLE))) { stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE); @@ -318,7 +319,6 @@ if (stream) { if ((b_session = switch_core_session_locate(b_uuid))) { switch_channel_t *b_channel = switch_core_session_get_channel(b_session); - switch_ivr_broadcast(b_uuid, stream, SMF_ECHO_ALEG | SMF_LOOP); switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_TRUE, 5000); switch_core_session_rwunlock(b_session); @@ -336,6 +336,7 @@ break; } } + if (b_uuid) { if ((b_session = switch_core_session_locate(b_uuid))) { switch_channel_t *b_channel = switch_core_session_get_channel(b_session); @@ -344,6 +345,7 @@ switch_core_session_rwunlock(b_session); } } + switch_channel_clear_flag(channel, CF_BROADCAST); } } Modified: freeswitch/trunk/src/switch_ivr_async.c ============================================================================== --- freeswitch/trunk/src/switch_ivr_async.c (original) +++ freeswitch/trunk/src/switch_ivr_async.c Wed Mar 12 21:08:42 2008 @@ -1277,8 +1277,8 @@ time_t now = switch_timestamp(NULL); char digit[2] = ""; int dval; - - if (!md) { + + if (!md || switch_channel_test_flag(channel, CF_INNER_BRIDGE)) { return SWITCH_STATUS_SUCCESS; } Modified: freeswitch/trunk/src/switch_ivr_bridge.c ============================================================================== --- freeswitch/trunk/src/switch_ivr_bridge.c (original) +++ freeswitch/trunk/src/switch_ivr_bridge.c Wed Mar 12 21:08:42 2008 @@ -98,6 +98,8 @@ switch_core_session_t *session_a, *session_b; uint32_t loop_count = 0; const char *app_name = NULL, *app_arg = NULL; + const char *hook_var = NULL; + int nosuspend = 0; #ifdef SWITCH_VIDEO_IN_THREADS struct vid_helper vh = { 0 }; uint32_t vid_launch = 0; @@ -122,7 +124,9 @@ } switch_channel_set_flag(chan_a, CF_BRIDGED); - + + nosuspend = switch_channel_test_flag(chan_a, CF_INNER_BRIDGE); + for (;;) { switch_channel_state_t b_state; switch_status_t status; @@ -130,17 +134,17 @@ loop_count++; if (!switch_channel_ready(chan_a)) { - break; + goto end_of_bridge_loop; } if ((b_state = switch_channel_get_state(chan_b)) >= CS_HANGUP) { - break; + goto end_of_bridge_loop; } if (switch_channel_test_flag(chan_a, CF_TRANSFER) || switch_channel_test_flag(chan_b, CF_TRANSFER)) { switch_channel_clear_flag(chan_a, CF_HOLD); switch_channel_clear_flag(chan_a, CF_SUSPEND); - break; + goto end_of_bridge_loop; } if (loop_count > 50 && switch_core_session_private_event_count(session_a)) { @@ -155,8 +159,8 @@ switch_channel_clear_flag(chan_b, CF_SUSPEND); } - if (switch_channel_test_flag(chan_a, CF_SUSPEND) || switch_channel_test_flag(chan_b, CF_SUSPEND)) { - switch_yield(1000); + if (!nosuspend && (switch_channel_test_flag(chan_a, CF_SUSPEND) || switch_channel_test_flag(chan_b, CF_SUSPEND))) { + switch_yield(10000); continue; } @@ -173,16 +177,23 @@ while (switch_channel_has_dtmf(chan_a)) { switch_dtmf_t dtmf = { 0, 0 }; if (switch_channel_dequeue_dtmf(chan_a, &dtmf) == SWITCH_STATUS_SUCCESS) { + int send_dtmf = 1; + if (input_callback) { - if (input_callback(session_a, (void *)&dtmf, SWITCH_INPUT_TYPE_DTMF, user_data, 0) != SWITCH_STATUS_SUCCESS) { + switch_status_t cb_status = input_callback(session_a, (void *)&dtmf, SWITCH_INPUT_TYPE_DTMF, user_data, 0); + + if (cb_status == SWITCH_STATUS_IGNORE) { + send_dtmf = 0; + } 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); - break; + goto end_of_bridge_loop; } } - - switch_core_session_send_dtmf(session_b, &dtmf); + if (send_dtmf) { + switch_core_session_send_dtmf(session_b, &dtmf); + } } } @@ -211,13 +222,13 @@ if (!ans_b && switch_channel_test_flag(chan_b, CF_ANSWERED)) { if (switch_channel_answer(chan_a) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(chan_a)); - break; + goto end_of_bridge_loop; } ans_a++; } else if (!pre_b && switch_channel_test_flag(chan_b, CF_EARLY_MEDIA)) { if (switch_channel_pre_answer(chan_a) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(chan_a)); - break; + goto end_of_bridge_loop; } pre_b++; } @@ -233,7 +244,7 @@ status = switch_core_session_read_video_frame(session_a, &read_frame, -1, 0); if (!SWITCH_READ_ACCEPTABLE(status)) { - break; + goto end_of_bridge_loop; } switch_core_session_write_video_frame(session_b, read_frame, -1, 0); @@ -252,15 +263,18 @@ if (switch_core_session_write_frame(session_b, read_frame, -1, stream_id) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "write: %s Bad Frame....[%u] Bubye!\n", switch_channel_get_name(chan_b), read_frame->datalen); - break; + goto end_of_bridge_loop; } } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "read: %s Bad Frame.... Bubye!\n", switch_channel_get_name(chan_a)); - break; + goto end_of_bridge_loop; } } + end_of_bridge_loop: + + #ifdef SWITCH_VIDEO_IN_THREADS if (vh.up) { vh.up = -1; @@ -271,7 +285,24 @@ } #endif + if (!nosuspend) { + hook_var = switch_channel_get_variable(chan_a, SWITCH_API_BRIDGE_END_VARIABLE); + } + if (!switch_strlen_zero(hook_var)) { + switch_stream_handle_t stream = { 0 }; + char *cmd = switch_core_session_strdup(session_a, hook_var); + char *arg = NULL; + if ((arg = strchr(cmd, ' '))) { + *arg++ = '\0'; + } + SWITCH_STANDARD_STREAM(stream); + switch_api_execute(cmd, arg, NULL, &stream); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\nPost-Bridge Command %s(%s):\n%s\n", cmd, arg, switch_str_nil((char *) stream.data)); + switch_safe_free(stream.data); + } + + if (switch_channel_get_state(chan_b) >= CS_HANGUP) { if (originator && switch_channel_ready(chan_a) && !switch_channel_test_flag(chan_a, CF_ANSWERED)) { switch_channel_hangup(chan_a, switch_channel_get_cause(chan_b)); @@ -282,8 +313,8 @@ msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE; msg.from = __FILE__; switch_core_session_receive_message(session_a, &msg); - - if (switch_channel_get_state(chan_a) < CS_HANGUP) { + + if (!nosuspend && switch_channel_get_state(chan_a) < CS_HANGUP) { if ((app_name = switch_channel_get_variable(chan_a, SWITCH_EXEC_AFTER_BRIDGE_APP_VARIABLE))) { switch_caller_extension_t *extension = NULL; if ((extension = switch_caller_extension_new(session_a, app_name, app_name)) == 0) { @@ -412,12 +443,18 @@ switch_channel_wait_for_state(channel, other_channel, CS_RESET); + if (switch_ivr_wait_for_answer(session, other_session) != SWITCH_STATUS_SUCCESS) { + switch_core_session_rwunlock(other_session); + switch_channel_hangup(channel, SWITCH_CAUSE_ORIGINATOR_CANCEL); + return SWITCH_STATUS_FALSE; + } + if (switch_channel_get_state(other_channel) == CS_RESET) { switch_channel_set_state(other_channel, CS_TRANSMIT); } switch_channel_wait_for_state(channel, other_channel, CS_TRANSMIT); - + switch_channel_clear_flag(channel, CF_TRANSFER); switch_channel_clear_flag(other_channel, CF_TRANSFER); switch_core_session_reset(session, SWITCH_TRUE); @@ -743,6 +780,9 @@ done: + switch_channel_clear_flag(caller_channel, CF_INNER_BRIDGE); + switch_channel_clear_flag(peer_channel, CF_INNER_BRIDGE); + if (br && switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(caller_channel, event); switch_event_fire(&event); @@ -773,6 +813,13 @@ originator_channel = switch_core_session_get_channel(originator_session); originatee_channel = switch_core_session_get_channel(originatee_session); + if (switch_channel_get_state(originator_channel) >= CS_HANGUP) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s is hungup refusing to bridge.\n", switch_channel_get_name(originatee_channel)); + switch_core_session_rwunlock(originator_session); + switch_core_session_rwunlock(originatee_session); + return SWITCH_STATUS_FALSE; + } + if (!switch_channel_test_flag(originator_channel, CF_ANSWERED)) { if (switch_channel_test_flag(originatee_channel, CF_ANSWERED)) { swap_session = originator_session; @@ -861,10 +908,10 @@ } else { switch_core_session_rwunlock(originator_session); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "no channel for originatee uuid %s\n", originatee_uuid); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "originatee uuid %s is not present\n", originatee_uuid); } } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "no channel for originator uuid %s\n", originator_uuid); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "originator uuid %s is not present\n", originator_uuid); } return status; Modified: freeswitch/trunk/src/switch_ivr_originate.c ============================================================================== --- freeswitch/trunk/src/switch_ivr_originate.c (original) +++ freeswitch/trunk/src/switch_ivr_originate.c Wed Mar 12 21:08:42 2008 @@ -367,7 +367,7 @@ } } - while (!(switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) { + while (switch_channel_ready(peer_channel) && !(switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) { int diff = (int)(switch_timestamp_now() - start); if (diff > timelimit) { @@ -1120,6 +1120,8 @@ } if (i != idx) { + const char *holding = NULL; + if (idx == IDX_CANCEL) { if (to) { reason = SWITCH_CAUSE_NO_ANSWER; @@ -1135,9 +1137,17 @@ reason = SWITCH_CAUSE_NO_ANSWER; } } - - - switch_channel_hangup(peer_channels[i], reason); + + if (caller_channel && i == 0) { + holding = switch_channel_get_variable(caller_channel, SWITCH_HOLDING_UUID_VARIABLE); + holding = switch_core_session_strdup(session, holding); + switch_channel_set_variable(caller_channel, SWITCH_HOLDING_UUID_VARIABLE, NULL); + } + if (holding) { + switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(peer_sessions[i])); + } else { + switch_channel_hangup(peer_channels[i], reason); + } } } 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 Mar 12 21:08:42 2008 @@ -1126,15 +1126,16 @@ args.buf = digit_buffer; args.buflen = digit_buffer_length; - if (!switch_strlen_zero(prompt_audio_file)) { + if (!switch_strlen_zero(prompt_audio_file) && strcasecmp(prompt_audio_file, "silence")) { status = switch_ivr_play_file(session, NULL, prompt_audio_file, &args); } - + if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { goto end; } len = strlen(digit_buffer); + if (len < min_digits && len < max_digits) { args.buf = digit_buffer + len; @@ -1142,7 +1143,7 @@ status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &terminator, timeout, 0, 0); } - + end: if (var_name && !switch_strlen_zero(digit_buffer)) { Modified: freeswitch/trunk/src/switch_rtp.c ============================================================================== --- freeswitch/trunk/src/switch_rtp.c (original) +++ freeswitch/trunk/src/switch_rtp.c Wed Mar 12 21:08:42 2008 @@ -1143,8 +1143,18 @@ switch_core_timer_sync(&rtp_session->timer); } else { check = (uint8_t) (switch_core_timer_check(&rtp_session->timer, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS); + if (check && switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTO_CNG) && + rtp_session->timer.samplecount >= (rtp_session->last_write_samplecount + (rtp_session->samples_per_interval * 50))) { + uint8_t data[10] = { 0 }; + switch_frame_flag_t frame_flags = SFF_NONE; + data[0] = 65; + rtp_session->cn++; + rtp_common_write(rtp_session, NULL, (void *) data, 2, rtp_session->cng_pt, 0, &frame_flags); + } } - } + } else if (bytes) { + check++; + } if (check) { do_2833(rtp_session); @@ -1295,19 +1305,6 @@ goto end; } - if (rtp_session->timer.interval) { - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTO_CNG) && - rtp_session->timer.samplecount >= (rtp_session->last_write_samplecount + (rtp_session->samples_per_interval * 50))) { - uint8_t data[10] = { 0 }; - switch_frame_flag_t frame_flags = SFF_NONE; - data[0] = 65; - rtp_session->cn++; - switch_mutex_lock(rtp_session->flag_mutex); - rtp_common_write(rtp_session, NULL, (void *) data, 2, rtp_session->cng_pt, 0, &frame_flags); - switch_mutex_unlock(rtp_session->flag_mutex); - } - } - if (check || (bytes && !rtp_session->timer.interval)) { if (!bytes && rtp_session->max_missed_packets) { if (++rtp_session->missed_count >= rtp_session->max_missed_packets) {
participants (1)
-
Freeswitch SVN