From d3e320ef56d0b3c4d46f2d9a0905b48e127e7be1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 16 Aug 2018 00:40:30 +0000 Subject: [PATCH] FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle); SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle); SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP); SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP); SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val); SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...); SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val); SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...); SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max); SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max); SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle); SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg); SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle); SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh); add switch_dial_handle_t *dh to end of args for switch_ivr_originate --- src/include/switch_ivr.h | 20 +- src/include/switch_types.h | 10 + .../mod_callcenter/mod_callcenter.c | 2 +- .../applications/mod_commands/mod_commands.c | 2 +- .../mod_conference/mod_conference.c | 4 +- .../applications/mod_dptools/mod_dptools.c | 12 +- src/mod/applications/mod_fifo/mod_fifo.c | 6 +- src/mod/applications/mod_lcr/mod_lcr.c | 2 +- src/mod/applications/mod_skel/mod_skel.c | 172 +++---- src/mod/endpoints/mod_sofia/sofia.c | 2 +- src/mod/endpoints/mod_verto/mod_verto.c | 2 +- src/mod/event_handlers/mod_rayo/mod_rayo.c | 2 +- src/mod/languages/mod_v8/src/fssession.cpp | 6 +- src/switch_cpp.cpp | 3 +- src/switch_ivr_originate.c | 437 ++++++++++++++++-- src/switch_swig.c | 2 +- 16 files changed, 540 insertions(+), 144 deletions(-) diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index a142927568..00cbc3438b 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -510,7 +510,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess const char *cid_name_override, const char *cid_num_override, switch_caller_profile_t *caller_profile_override, - switch_event_t *ovars, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause); + switch_event_t *ovars, switch_originate_flag_t flags, + switch_call_cause_t *cancel_cause, + switch_dial_handle_t *dh); SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_session_t *session, switch_core_session_t **bleg, @@ -1024,6 +1026,22 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_video_write_overlay_session(switch_co SWITCH_DECLARE(switch_status_t) switch_ivr_capture_text(switch_core_session_t *session, switch_bool_t on); +SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle); +SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle); +SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP); +SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *dial_string); +SWITCH_DECLARE(void) switch_dial_leg_list_add_leg_printf(switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *fmt, ...); +SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val); +SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...); +SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val); +SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...); +SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max); +SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max); +SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle); +SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg); +SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle); +SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh); + /** @} */ SWITCH_END_EXTERN_C diff --git a/src/include/switch_types.h b/src/include/switch_types.h index c1d48cbd80..25c3b97c85 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -2786,6 +2786,16 @@ typedef struct secure_settings_s { /* max number of MKI in a single crypto line supported */ #define SWITCH_CRYPTO_MKI_MAX 20 +struct switch_dial_handle_s; +typedef struct switch_dial_handle_s switch_dial_handle_t; + +struct switch_dial_leg_s; +typedef struct switch_dial_leg_s switch_dial_leg_t; + +struct switch_dial_leg_list_s; +typedef struct switch_dial_leg_list_s switch_dial_leg_list_t; + + SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index 2ac47a11d2..bc320eb0d2 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -1707,7 +1707,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa dialstr = switch_channel_expand_variables(member_channel, h->originate_string); switch_channel_set_app_flag_key(CC_APP_KEY, member_channel, CC_APP_AGENT_CONNECTING); - status = switch_ivr_originate(NULL, &agent_session, &cause, dialstr, 60, NULL, cid_name ? cid_name : h->member_cid_name, cid_number ? cid_number : h->member_cid_number, NULL, ovars, SOF_NONE, NULL); + status = switch_ivr_originate(NULL, &agent_session, &cause, dialstr, 60, NULL, cid_name ? cid_name : h->member_cid_name, cid_number ? cid_number : h->member_cid_number, NULL, ovars, SOF_NONE, NULL, NULL); /* Search for loopback agent */ if (status == SWITCH_STATUS_SUCCESS) { diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 1c3e59adfb..5ed543f402 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -5042,7 +5042,7 @@ SWITCH_STANDARD_API(originate_function) timeout = atoi(argv[6]); } - if (switch_ivr_originate(NULL, &caller_session, &cause, aleg, timeout, NULL, cid_name, cid_num, NULL, NULL, SOF_NONE, NULL) != SWITCH_STATUS_SUCCESS + if (switch_ivr_originate(NULL, &caller_session, &cause, aleg, timeout, NULL, cid_name, cid_num, NULL, NULL, SOF_NONE, NULL, NULL) != SWITCH_STATUS_SUCCESS || !caller_session) { stream->write_function(stream, "-ERR %s\n", switch_channel_cause2str(cause)); goto done; diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 6efb7c72df..8bfee901f8 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1520,7 +1520,7 @@ switch_status_t conference_outcall(conference_obj_t *conference, if (conference == NULL) { char *dialstr = switch_mprintf("{ignore_early_media=true}%s", bridgeto); - status = switch_ivr_originate(NULL, &peer_session, cause, dialstr, 60, NULL, cid_name, cid_num, NULL, var_event, SOF_NO_LIMITS, NULL); + status = switch_ivr_originate(NULL, &peer_session, cause, dialstr, 60, NULL, cid_name, cid_num, NULL, var_event, SOF_NO_LIMITS, NULL, NULL); switch_safe_free(dialstr); if (status != SWITCH_STATUS_SUCCESS) { @@ -1562,7 +1562,7 @@ switch_status_t conference_outcall(conference_obj_t *conference, } - status = switch_ivr_originate(session, &peer_session, cause, bridgeto, timeout, NULL, cid_name, cid_num, NULL, var_event, SOF_NO_LIMITS, cancel_cause); + status = switch_ivr_originate(session, &peer_session, cause, bridgeto, timeout, NULL, cid_name, cid_num, NULL, var_event, SOF_NO_LIMITS, cancel_cause, NULL); switch_mutex_lock(conference->mutex); conference->originating--; switch_mutex_unlock(conference->mutex); diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 3d22b350ef..b69a0a4025 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -2565,7 +2565,7 @@ void *SWITCH_THREAD_FUNC att_thread_run(switch_thread_t *thread, void *obj) switch_core_session_rwunlock(b_session); } - if (switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL) + if (switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL) != SWITCH_STATUS_SUCCESS || !peer_session) { switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond); goto end; @@ -3480,7 +3480,7 @@ SWITCH_STANDARD_APP(audio_bridge_function) status = switch_ivr_originate(NULL, &peer_session, &cause, camp_data, campon_timeout, NULL, NULL, NULL, NULL, NULL, SOF_NONE, - switch_channel_get_cause_ptr(caller_channel)); + switch_channel_get_cause_ptr(caller_channel), NULL); } while (camping && switch_channel_ready(caller_channel)); @@ -3509,7 +3509,7 @@ SWITCH_STANDARD_APP(audio_bridge_function) } else { if ((status = - switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL)) != SWITCH_STATUS_SUCCESS) { + switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL)) != SWITCH_STATUS_SUCCESS) { fail = 1; } } @@ -4166,7 +4166,7 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session if (switch_ivr_originate(session, new_session, &cause, dest, timelimit, NULL, - cid_name_override, cid_num_override, NULL, var_event, myflags, cancel_cause) == SWITCH_STATUS_SUCCESS) { + cid_name_override, cid_num_override, NULL, var_event, myflags, cancel_cause, NULL) == SWITCH_STATUS_SUCCESS) { const char *context; switch_caller_profile_t *cp; @@ -4364,7 +4364,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, cause = SWITCH_CAUSE_INVALID_IE_CONTENTS; } else if (switch_ivr_originate(session, new_session, &cause, d_dest, timelimit, NULL, cid_name_override, cid_num_override, outbound_profile, var_event, myflags, - cancel_cause) == SWITCH_STATUS_SUCCESS) { + cancel_cause, NULL) == SWITCH_STATUS_SUCCESS) { const char *context; switch_caller_profile_t *cp; @@ -5627,7 +5627,7 @@ void *SWITCH_THREAD_FUNC page_thread(switch_thread_t *thread, void *obj) switch_memory_pool_t *pool = pd->pool; - if (switch_ivr_originate(NULL, &session, &cause, pd->dial_str, SWITCH_DEFAULT_TIMEOUT, NULL, NULL, NULL, NULL, pd->var_event, SOF_NONE, NULL) == SWITCH_STATUS_SUCCESS) { + if (switch_ivr_originate(NULL, &session, &cause, pd->dial_str, SWITCH_DEFAULT_TIMEOUT, NULL, NULL, NULL, NULL, pd->var_event, SOF_NONE, NULL, NULL) == SWITCH_STATUS_SUCCESS) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_set_variable(channel, "page_file", pd->path); diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 2820eab070..28429c7244 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1643,7 +1643,7 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr if (globals.debug) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s dialing: %s\n", node->name, originate_string); - status = switch_ivr_originate(NULL, &session, &cause, originate_string, timeout, NULL, NULL, NULL, NULL, ovars, SOF_NONE, &cancel_cause); + status = switch_ivr_originate(NULL, &session, &cause, originate_string, timeout, NULL, NULL, NULL, NULL, ovars, SOF_NONE, &cancel_cause, NULL); del_caller_outbound_call(id); @@ -1847,7 +1847,7 @@ static void *SWITCH_THREAD_FUNC outbound_enterprise_thread_run(switch_thread_t * sql = switch_mprintf("update fifo_outbound set ring_count=ring_count+1 where uuid='%q'", h->uuid); fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); - status = switch_ivr_originate(NULL, &session, &cause, originate_string, h->timeout, NULL, NULL, NULL, NULL, ovars, SOF_NONE, NULL); + status = switch_ivr_originate(NULL, &session, &cause, originate_string, h->timeout, NULL, NULL, NULL, NULL, ovars, SOF_NONE, NULL, NULL); if (status != SWITCH_STATUS_SUCCESS) { sql = switch_mprintf("update fifo_outbound set ring_count=ring_count-1, " @@ -3185,7 +3185,7 @@ SWITCH_STANDARD_APP(fifo_function) } } - if (switch_ivr_originate(session, &other_session, &cause, url, 120, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_ivr_originate(session, &other_session, &cause, url, 120, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL) != SWITCH_STATUS_SUCCESS) { other_session = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Originate to [%s] failed, cause: %s\n", url, switch_channel_cause2str(cause)); diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index 00673f12e5..a9adb3db10 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -1511,7 +1511,7 @@ static switch_call_cause_t lcr_outgoing_channel(switch_core_session_t *session, } } if (switch_ivr_originate(session, new_session, &cause, cur_route->dialstring, timelimit, NULL, - cid_name_override, cid_num_override, NULL, var_event, myflags, cancel_cause) == SWITCH_STATUS_SUCCESS) { + cid_name_override, cid_num_override, NULL, var_event, myflags, cancel_cause, NULL) == SWITCH_STATUS_SUCCESS) { const char *context; switch_caller_profile_t *cp; diff --git a/src/mod/applications/mod_skel/mod_skel.c b/src/mod/applications/mod_skel/mod_skel.c index b1f800043b..130d08d05b 100644 --- a/src/mod/applications/mod_skel/mod_skel.c +++ b/src/mod/applications/mod_skel/mod_skel.c @@ -117,100 +117,108 @@ static switch_status_t do_config(switch_bool_t reload) //#define _switch_stun_packet_next_attribute(attribute, end) (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + _switch_stun_attribute_padded_length(attribute))) && ((void *)attribute < end) && ((void *)(attribute + _switch_stun_attribute_padded_length(attribute)) < end)) +#define MAX_PEERS 128 SWITCH_STANDARD_API(skel_function) { - switch_event_t *event; - unsigned char frame_buffer[8192] = {0}; - uint8_t buf[256] = { 0 }; - switch_stun_packet_t *packet; - char user_name[] = "0000000000000000:1111111111111111"; - //char user_name[] = "0000000000000000"; - void *end_buf; - switch_stun_packet_attribute_t *attr; - int xlen = 0; - - packet = switch_stun_packet_build_header(SWITCH_STUN_BINDING_REQUEST, NULL, buf); - - printf("1len %d %d\n", ntohs(packet->header.length), xlen); - - switch_stun_packet_attribute_add_username(packet, user_name, strlen(user_name)); - printf("2len %d %d\n", ntohs(packet->header.length), xlen); - - switch_stun_packet_attribute_add_controlled(packet); - - //switch_stun_packet_attribute_add_password(packet, user_name, strlen(user_name)); - //printf("3len %d %d\n", ntohs(packet->header.length), xlen); - - //switch_stun_packet_attribute_add_use_candidate(packet); - - switch_stun_packet_attribute_add_integrity(packet, "FUCK"); - switch_stun_packet_attribute_add_fingerprint(packet); + switch_dial_handle_t *dh; + switch_dial_leg_list_t *ll; + switch_dial_leg_t *leg = NULL; + int timeout = 0; + char *peer_names[MAX_PEERS] = { 0 }; + switch_event_t *peer_vars[MAX_PEERS] = { 0 }; + int i; + switch_core_session_t *peer_session = NULL; + switch_call_cause_t cause; + + switch_dial_handle_create(&dh); - end_buf = buf + ((sizeof(buf) > packet->header.length) ? packet->header.length : sizeof(buf)); + switch_dial_handle_add_global_var(dh, "ignore_early_media", "true"); + switch_dial_handle_add_global_var_printf(dh, "coolness_count", "%d", 12); + + + //// SET TO 1 FOR AND LIST example or to 0 for OR LIST example +#if 0 + switch_dial_handle_add_leg_list(dh, &ll); + + switch_dial_leg_list_add_leg(ll, &leg, "sofia/internal/foo1@bar1.com"); + timeout += 10; + switch_dial_handle_add_leg_var_printf(leg, "leg_timeout", "%d", timeout); + + switch_dial_leg_list_add_leg(ll, &leg, "sofia/internal/foo2@bar2.com"); + timeout += 10; + switch_dial_handle_add_leg_var_printf(leg, "leg_timeout", "%d", timeout); + + + switch_dial_leg_list_add_leg(ll, &leg, "sofia/internal/foo3@bar3.com"); + timeout += 10; + switch_dial_handle_add_leg_var_printf(leg, "leg_timeout", "%d", timeout); + + + switch_dial_leg_list_add_leg(ll, &leg, "sofia/internal/3000@cantina.freeswitch.org"); + + +#else + + switch_dial_handle_add_leg_list(dh, &ll); + switch_dial_leg_list_add_leg(ll, &leg, "sofia/internal/foo1@bar1.com"); + timeout += 10; + switch_dial_handle_add_leg_var_printf(leg, "leg_timeout", "%d", timeout); + + switch_dial_handle_add_leg_list(dh, &ll); + switch_dial_leg_list_add_leg(ll, &leg, "sofia/internal/foo2@bar2.com"); + timeout += 10; + switch_dial_handle_add_leg_var_printf(leg, "leg_timeout", "%d", timeout); + + switch_dial_handle_add_leg_list(dh, &ll); + switch_dial_leg_list_add_leg(ll, &leg, "sofia/internal/foo3@bar3.com"); + timeout += 10; + switch_dial_handle_add_leg_var_printf(leg, "leg_timeout", "%d", timeout); + + + switch_dial_handle_add_leg_list(dh, &ll); + switch_dial_leg_list_add_leg(ll, &leg, "sofia/internal/3000@cantina.freeswitch.org"); +#endif + + + + /////// JUST DUMP SOME OF IT TO SEE FIRST + + switch_dial_handle_get_peers(dh, 0, peer_names, MAX_PEERS); + switch_dial_handle_get_vars(dh, 0, peer_vars, MAX_PEERS); - switch_stun_packet_first_attribute(packet, attr); + + for(i = 0; i < MAX_PEERS; i++) { + if (peer_names[i]) { + char *foo; + + printf("peer: [%s]\n", peer_names[i]); - xlen = sizeof(switch_stun_packet_header_t); - - printf("len %d %d\n", ntohs(packet->header.length), xlen); - - do { - printf("WTF %p %d %d:(%d)\n", (void *)attr, ntohs(attr->type), ntohs(attr->length), switch_stun_attribute_padded_length_hbo(attr)); - - if (!switch_stun_packet_next_attribute_hbo(attr, end_buf)) { - break; + if (peer_vars[i]) { + if (switch_event_serialize(peer_vars[i], &foo, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { + printf("%s\n", foo); + } + } + printf("\n\n"); } - - xlen += 4+switch_stun_attribute_padded_length_hbo(attr); - } while (xlen <= ntohs(packet->header.length)); - - - - - return SWITCH_STATUS_SUCCESS; - - do_config(SWITCH_TRUE); - - if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { - switch_size_t len = 0; - int x = 0; - - /* populate the event with some headers */ - - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "testing", "true"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "foo", "bar"); - - for (x = 0; x < 10; x++) { - char name[128]; - switch_snprintf(name, sizeof(name), "test-header-%d", x); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, name, "value-%d", x); - } - - - /* Nothing up my sleeve, here is the event */ - - DUMP_EVENT(event); - - - /* ok, serialize it into frame_buffer and destroy the event *poof* */ - len = sizeof(frame_buffer); - switch_event_binary_serialize(event, (void *)frame_buffer, &len); - switch_event_destroy(&event); - - - /* wave the magic wand and feed frame_buffer to deserialize */ - switch_event_binary_deserialize(&event, (void *)frame_buffer, len, SWITCH_FALSE); - - /* TA DA */ - DUMP_EVENT(event); - - switch_event_destroy(&event); } + switch_ivr_originate(NULL, &peer_session, &cause, NULL, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, dh); + + if (peer_session) { + switch_ivr_session_transfer(peer_session, "3500", "XML", NULL); + switch_core_session_rwunlock(peer_session); + } + + + switch_dial_handle_destroy(&dh); + + + + return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 181e40485b..e416dbbd14 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -8541,7 +8541,7 @@ void *SWITCH_THREAD_FUNC nightmare_xfer_thread_run(switch_thread_t *thread, void switch_channel_t *channel_a = switch_core_session_get_channel(session); if ((status = switch_ivr_originate(NULL, &tsession, &cause, nhelper->exten_with_params, timeout, NULL, NULL, NULL, - switch_channel_get_caller_profile(channel_a), nhelper->vars, SOF_NONE, NULL)) == SWITCH_STATUS_SUCCESS) { + switch_channel_get_caller_profile(channel_a), nhelper->vars, SOF_NONE, NULL, NULL)) == SWITCH_STATUS_SUCCESS) { if (switch_channel_up(channel_a)) { if (switch_true(switch_channel_get_variable(channel_a, "recording_follow_transfer"))) { diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 3cd84293f9..f0efed4907 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -5480,7 +5480,7 @@ static switch_call_cause_t verto_outgoing_channel(switch_core_session_t *session } if (switch_ivr_originate(session, new_session, &cause, dial_str, 0, NULL, - NULL, NULL, outbound_profile, var_event, myflags, cancel_cause) == SWITCH_STATUS_SUCCESS) { + NULL, NULL, outbound_profile, var_event, myflags, cancel_cause, NULL) == SWITCH_STATUS_SUCCESS) { switch_core_session_rwunlock(*new_session); } diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index e083ae6109..d1bdd77896 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -2801,7 +2801,7 @@ static void *SWITCH_THREAD_FUNC rayo_dial_thread(switch_thread_t *thread, void * switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "dial: Using dialstring: %s\n", dialstring); /* response will be sent when originate event is received- otherwise error is returned */ - if (switch_ivr_originate(NULL, &called_session, &cause, dialstring, dial_timeout_sec, NULL, NULL, NULL, NULL, originate_vars, SOF_NONE, NULL) == SWITCH_STATUS_SUCCESS && called_session) { + if (switch_ivr_originate(NULL, &called_session, &cause, dialstring, dial_timeout_sec, NULL, NULL, NULL, NULL, originate_vars, SOF_NONE, NULL, NULL) == SWITCH_STATUS_SUCCESS && called_session) { /* start APP */ switch_caller_extension_t *extension = NULL; switch_channel_t *called_channel = switch_core_session_get_channel(called_session); diff --git a/src/mod/languages/mod_v8/src/fssession.cpp b/src/mod/languages/mod_v8/src/fssession.cpp index ca135206df..a34406a493 100644 --- a/src/mod/languages/mod_v8/src/fssession.cpp +++ b/src/mod/languages/mod_v8/src/fssession.cpp @@ -1603,7 +1603,8 @@ void *FSSession::Construct(const v8::FunctionCallbackInfo& info) old_obj = JSBase::GetInstance(Handle::Cast(info[1])); } if (switch_ivr_originate(old_obj ? old_obj->_session : NULL, - &session_obj->_session, &session_obj->_cause, uuid, 60, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL) == SWITCH_STATUS_SUCCESS) { + &session_obj->_session, &session_obj->_cause, uuid, 60, + NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL) == SWITCH_STATUS_SUCCESS) { switch_set_flag(session_obj, S_HUP); } else { /* This will return the Session object, but with no C++ instance related to it */ @@ -1765,7 +1766,8 @@ JS_SESSION_FUNCTION_IMPL(Originate) caller_profile = switch_caller_profile_new(pool, username, dialplan, cid_name, cid_num, network_addr, ani, aniii, rdnis, "mod_v8", context, dest.c_str()); status = - switch_ivr_originate(session, &peer_session, &this->_cause, dest.c_str(), to.length() > 0 ? atoi(to.c_str()) : 60, NULL, NULL, NULL, caller_profile, NULL, SOF_NONE, NULL); + switch_ivr_originate(session, &peer_session, &this->_cause, + dest.c_str(), to.length() > 0 ? atoi(to.c_str()) : 60, NULL, NULL, NULL, caller_profile, NULL, SOF_NONE, NULL, NULL); if (status != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot Create Outgoing Channel! [%s]\n", dest.c_str()); diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index 342d91a187..d703bbdc31 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -619,7 +619,7 @@ SWITCH_DECLARE_CONSTRUCTOR CoreSession::CoreSession(char *nuuid, CoreSession *a_ allocated = 1; } else { cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - if (switch_ivr_originate(a_leg ? a_leg->session : NULL, &session, &cause, nuuid, 60, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL) + if (switch_ivr_originate(a_leg ? a_leg->session : NULL, &session, &cause, nuuid, 60, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL) == SWITCH_STATUS_SUCCESS) { channel = switch_core_session_get_channel(session); allocated = 1; @@ -1249,6 +1249,7 @@ SWITCH_DECLARE(int) CoreSession::originate(CoreSession *a_leg_session, char *des NULL, NULL, SOF_NONE, + NULL, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error Creating Outgoing Channel! [%s]\n", dest); goto failed; diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 872ed4ff57..a3d4edb697 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -80,6 +80,32 @@ static const switch_state_handler_table_t originate_state_handlers = { /*.on_consume_media */ originate_on_consume_media_transmit }; +#define MAX_PEERS 128 + +struct switch_dial_handle_s; + + +struct switch_dial_leg_list_s { + int leg_idx; + switch_dial_leg_t *legs[MAX_PEERS]; + struct switch_dial_handle_s *handle; +}; + +struct switch_dial_leg_s { + char *dial_string; + switch_event_t *leg_vars; + struct switch_dial_handle_s *handle; + struct switch_dial_leg_s *next; +}; + +struct switch_dial_handle_s { + int is_sub; + int leg_list_idx; + switch_dial_leg_list_t *leg_lists[MAX_PEERS]; + switch_event_t *global_vars; + switch_memory_pool_t *pool; +}; + typedef struct { switch_core_session_t *down_session; @@ -1366,7 +1392,7 @@ static switch_status_t setup_ringback(originate_global_t *oglobals, originate_st } -#define MAX_PEERS 128 + typedef struct { switch_core_session_t *session; @@ -1404,7 +1430,12 @@ static void *SWITCH_THREAD_FUNC enterprise_originate_thread(switch_thread_t *thr handle->bridgeto, handle->timelimit_sec, handle->table, handle->cid_name_override, - handle->cid_num_override, handle->caller_profile_override, handle->ovars, handle->flags, &handle->cancel_cause); + handle->cid_num_override, + handle->caller_profile_override, + handle->ovars, + handle->flags, + &handle->cancel_cause, + NULL); handle->done = 1; @@ -1936,7 +1967,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess const char *cid_name_override, const char *cid_num_override, switch_caller_profile_t *caller_profile_override, - switch_event_t *ovars, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) + switch_event_t *ovars, switch_originate_flag_t flags, + switch_call_cause_t *cancel_cause, + switch_dial_handle_t *dh) { originate_status_t originate_status[MAX_PEERS] = { {0} }; switch_originate_flag_t dftflags = SOF_NONE, myflags = dftflags; @@ -1945,6 +1978,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_status_t status = SWITCH_STATUS_SUCCESS; switch_channel_t *caller_channel = NULL; char *peer_names[MAX_PEERS] = { 0 }; + switch_event_t *peer_vars[MAX_PEERS] = { 0 }; switch_core_session_t *new_session = NULL, *peer_session = NULL; switch_caller_profile_t *new_profile = NULL, *caller_caller_profile; char *chan_type = NULL, *chan_data; @@ -1985,7 +2019,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess const char *aniii_override = NULL; const char *ent_aleg_uuid = NULL; switch_core_session_t *a_session = session, *l_session = NULL; - + char *event_string; + + if (!bridgeto || dh) { + bridgeto = ""; + } + if (session) { caller_channel = switch_core_session_get_channel(session); @@ -2138,7 +2177,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess || switch_true(switch_core_get_variable("origination_nested_vars")) || switch_stristr("origination_nested_vars=true", data)) { oglobals.check_vars = SWITCH_FALSE; } - + + if (dh) { + switch_event_t *vp = switch_dial_handle_get_global_vars(dh); + if (vp) { + switch_event_dup(&var_event, vp); + } + } /* extract channel variables, allowing multiple sets of braces */ if (*data == '<') { @@ -2167,14 +2212,18 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess data = parsed; } - - + + if (dh && var_event && switch_event_serialize(var_event, &event_string, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Global Vars\n======================\n%s\n", event_string); + switch_safe_free(event_string); + } + /* strip leading spaces (again) */ while (data && *data && *data == ' ') { data++; } - if (zstr(data)) { + if (zstr(data) && !dh) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "No origination URL specified!\n"); status = SWITCH_STATUS_GENERR; goto done; @@ -2569,14 +2618,23 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_safe_free(loop_data); loop_data = strdup(data); switch_assert(loop_data); - or_argc = switch_separate_string(loop_data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0]))); + if (dh) { + or_argc = switch_dial_handle_get_total(dh); + } else { + or_argc = switch_separate_string(loop_data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0]))); + } + if ((flags & SOF_NOBLOCK) && or_argc > 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Only calling the first element in the list in this mode.\n"); or_argc = 1; } - - + + if (or_argc <= 0) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Nothing to do\n"); + goto outer_for; + } + for (r = 0; r < or_argc && (!cancel_cause || *cancel_cause == 0); r++) { char *p, *end = NULL; int q = 0, alt = 0; @@ -2625,46 +2683,51 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess last_retry_start = switch_micro_time_now(); } - p = pipe_names[r]; + if (!dh) { + p = pipe_names[r]; - while (p && *p) { - if (!end && *p == '[') { - end = switch_find_end_paren(p, '[', ']'); - if (*(p+1) == '^' && *(p + 2) == '^') { - alt = 1; - } else { - alt = 0; + while (p && *p) { + if (!end && *p == '[') { + end = switch_find_end_paren(p, '[', ']'); + if (*(p+1) == '^' && *(p + 2) == '^') { + alt = 1; + } else { + alt = 0; + } + q = 0; } - q = 0; - } - if (*p == '\'') { - q = !q; - } - - if (end && p < end && *p == ',' && *(p-1) != '\\') { - - if (q || alt) { - *p = QUOTED_ESC_COMMA; - } else { - *p = UNQUOTED_ESC_COMMA; + if (*p == '\'') { + q = !q; } - } - if (p == end) { - end = NULL; - } + if (end && p < end && *p == ',' && *(p-1) != '\\') { - p++; + if (q || alt) { + *p = QUOTED_ESC_COMMA; + } else { + *p = UNQUOTED_ESC_COMMA; + } + } + + if (p == end) { + end = NULL; + } + + p++; + } + + and_argc = switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0]))); + } else { + and_argc = switch_dial_handle_get_peers(dh, r, peer_names, MAX_PEERS); + switch_dial_handle_get_vars(dh, r, peer_vars, MAX_PEERS); } - - and_argc = switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0]))); - + if ((flags & SOF_NOBLOCK) && and_argc > 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Only calling the first element in the list in this mode.\n"); and_argc = 1; } - + for (i = 0; i < and_argc; i++) { const char *current_variable; switch_event_t *local_var_event = NULL, *originate_var_event = NULL; @@ -2710,7 +2773,20 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } + if (peer_vars[i]) { + if (local_var_event) { + switch_event_merge(local_var_event, peer_vars[i]); + } else { + switch_event_dup(&local_var_event, peer_vars[i]); + } + if (dh && local_var_event && switch_event_serialize(local_var_event, &event_string, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Local Vars for %s\n======================\n%s\n", + peer_names[i], event_string); + switch_safe_free(event_string); + } + } + /* strip leading spaces (again) */ while (chan_type && *chan_type && *chan_type == ' ') { chan_type++; @@ -4097,6 +4173,287 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess return status; } +SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle) +{ + switch_dial_handle_t *hp; + switch_memory_pool_t *pool = NULL; + + switch_core_new_memory_pool(&pool); + switch_assert(pool); + + hp = switch_core_alloc(pool, sizeof(*hp)); + switch_assert(hp); + + hp->pool = pool; + + *handle = hp; + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle) +{ + switch_dial_handle_t *hp = *handle; + switch_memory_pool_t *pool = NULL; + + *handle = NULL; + + if (hp) { + int i, j; + + for (i = 0; i < hp->leg_list_idx; i++) { + for(j = 0; j < hp->leg_lists[i]->leg_idx; j++) { + switch_event_destroy(&hp->leg_lists[i]->legs[j]->leg_vars); + } + } + + switch_event_destroy(&hp->global_vars); + pool = hp->pool; + hp = NULL; + switch_core_destroy_memory_pool(&pool); + } +} + +SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP) +{ + switch_dial_leg_list_t *leg_list; + + switch_assert(handle); + + leg_list = switch_core_alloc(handle->pool, sizeof(*leg_list)); + leg_list->handle = handle; + + handle->leg_lists[handle->leg_list_idx++] = leg_list; + + *leg_listP = leg_list; +} + +SWITCH_DECLARE(void) switch_dial_leg_list_add_leg_printf(switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *fmt, ...) +{ + int ret = 0; + char *data = NULL; + va_list ap; + + va_start(ap, fmt); + ret = switch_vasprintf(&data, fmt, ap); + va_end(ap); + + if (ret == -1) { + abort(); + } + + switch_dial_leg_list_add_leg(parent, legP, data); + free(data); +} + +SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *dial_string) +{ + switch_dial_leg_t *leg; + + switch_assert(parent); + + leg = switch_core_alloc(parent->handle->pool, sizeof(*leg)); + leg->handle = parent->handle; + leg->dial_string = switch_core_strdup(parent->handle->pool, dial_string); + + parent->legs[parent->leg_idx++] = leg; + + if (legP) { + *legP = leg; + } +} + +SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val) +{ + switch_assert(handle); + + if (!handle->global_vars) { + switch_event_create_plain(&handle->global_vars, SWITCH_EVENT_CHANNEL_DATA); + } + + switch_event_add_header_string(handle->global_vars, SWITCH_STACK_BOTTOM, var, val); +} + +SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...) +{ + int ret = 0; + char *data = NULL; + va_list ap; + + va_start(ap, fmt); + ret = switch_vasprintf(&data, fmt, ap); + va_end(ap); + + if (ret == -1) { + abort(); + } + + switch_dial_handle_add_global_var(handle, var, data); + free(data); +} + +SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val) +{ + if (!leg) return SWITCH_STATUS_NOTFOUND; + + if (!leg->leg_vars) { + switch_event_create_plain(&leg->leg_vars, SWITCH_EVENT_CHANNEL_DATA); + } + + switch_event_add_header_string(leg->leg_vars, SWITCH_STACK_BOTTOM, var, val); + + return SWITCH_STATUS_SUCCESS; + +} + +SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...) +{ + int ret = 0; + char *data = NULL; + va_list ap; + switch_status_t status; + + va_start(ap, fmt); + ret = switch_vasprintf(&data, fmt, ap); + va_end(ap); + + if (ret == -1) { + abort(); + } + + status = switch_dial_handle_add_leg_var(leg, var, data); + + free(data); + + return status; +} + +SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle) +{ + return handle->leg_list_idx; +} + +SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max) +{ + int i, j = 0; + + if (!handle->leg_lists[idx]) return 0; + + for (i = 0; i < max && handle->leg_lists[idx]->legs[i]; i++) { + array[j++] = handle->leg_lists[idx]->legs[i]->dial_string; + } + + return j; +} + + +SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max) +{ + int i, j = 0; + + if (!handle->leg_lists[idx]) return 0; + + for (i = 0; i < max && handle->leg_lists[idx]->legs[i]; i++) { + array[j++] = handle->leg_lists[idx]->legs[i]->leg_vars; + } + + return j; +} + + +SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle) +{ + switch_assert(handle); + + return handle->global_vars; +} + +SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg) +{ + switch_assert(leg); + + return leg->leg_vars; +} + + +static switch_status_t o_bridge_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) +{ + char *str = (char *) buf; + + if (str && input && itype == SWITCH_INPUT_TYPE_DTMF) { + switch_dtmf_t *dtmf = (switch_dtmf_t *) input; + if (strchr(str, dtmf->digit)) { + return SWITCH_STATUS_BREAK; + } + } + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh) +{ + switch_channel_t *caller_channel = switch_core_session_get_channel(session); + switch_core_session_t *peer_session = NULL; + switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; + switch_status_t status = SWITCH_STATUS_FALSE; + int fail = 0; + + if ((status = switch_ivr_originate(session, + &peer_session, + &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, dh)) != SWITCH_STATUS_SUCCESS) { + fail = 1; + } + + + if (fail) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Originate Failed. Cause: %s\n", switch_channel_cause2str(cause)); + + switch_channel_set_variable(caller_channel, "originate_failed_cause", switch_channel_cause2str(cause)); + + switch_channel_handle_cause(caller_channel, cause); + + return; + } else { + + switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); + if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE)) || + switch_true(switch_channel_get_variable(peer_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE))) { + switch_channel_set_flag(caller_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE); + } + + if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) { + switch_ivr_signal_bridge(session, peer_session); + } else { + char *a_key = (char *) switch_channel_get_variable(caller_channel, "bridge_terminate_key"); + char *b_key = (char *) switch_channel_get_variable(peer_channel, "bridge_terminate_key"); + int ok = 0; + switch_input_callback_function_t func = NULL; + + if (a_key) { + a_key = switch_core_session_strdup(session, a_key); + ok++; + } + if (b_key) { + b_key = switch_core_session_strdup(session, b_key); + ok++; + } + if (ok) { + func = o_bridge_on_dtmf; + } else { + a_key = NULL; + b_key = NULL; + } + + switch_ivr_multi_threaded_bridge(session, peer_session, func, a_key, b_key); + } + + if (peer_session) { + switch_core_session_rwunlock(peer_session); + } + } +} + + + /* For Emacs: * Local Variables: * mode:c diff --git a/src/switch_swig.c b/src/switch_swig.c index bf2ce479fd..f0c482ad14 100644 --- a/src/switch_swig.c +++ b/src/switch_swig.c @@ -237,7 +237,7 @@ int fs_switch_ivr_originate(switch_core_session_t *session, switch_core_session_ timelimit = atoi(var); } - if (switch_ivr_originate(session, &peer_session, &cause, bridgeto, timelimit, NULL, NULL, NULL, NULL, SOF_NONE) != SWITCH_STATUS_SUCCESS) { + if (switch_ivr_originate(session, &peer_session, &cause, bridgeto, timelimit, NULL, NULL, NULL, NULL, SOF_NONE, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Cannot Create Outgoing Channel!\n"); switch_channel_hangup(caller_channel, SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL); return;