diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index a50c3b83f1..7cd448196d 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -210,6 +210,8 @@ SWITCH_DECLARE(char *) switch_channel_get_uuid(switch_channel_t *channel); */ SWITCH_DECLARE(switch_status_t) switch_channel_set_variable(switch_channel_t *channel, const char *varname, const char *value); +SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_partner(switch_channel_t *channel, const char *varname, const char *value); + /*! \brief Retrieve a variable from a given channel \param channel channel to retrieve variable from diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 577a3d186b..d6e034d580 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -698,12 +698,15 @@ SWITCH_DECLARE(void) switch_core_service_session(switch_core_session_t *session, \param caller_profile the originator's caller profile \param new_session a NULL pointer to aim at the newly created session \param pool optional existing memory pool to donate to the session + \paeam flags flags to use \return the cause code of the attempted call */ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_core_session_t *session, char *endpoint_name, switch_caller_profile_t *caller_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool); + switch_core_session_t **new_session, + switch_memory_pool_t **pool, + switch_originate_flag_t flags); /*! \brief Receive a message on a given session diff --git a/src/include/switch_core_event_hook.h b/src/include/switch_core_event_hook.h index 8f48d87df7..0e2f5751b3 100644 --- a/src/include/switch_core_event_hook.h +++ b/src/include/switch_core_event_hook.h @@ -48,7 +48,8 @@ typedef struct switch_io_event_hook_waitfor_write switch_io_event_hook_waitfor_w typedef struct switch_io_event_hook_send_dtmf switch_io_event_hook_send_dtmf_t; typedef struct switch_io_event_hook_recv_dtmf switch_io_event_hook_recv_dtmf_t; typedef struct switch_io_event_hook_state_change switch_io_event_hook_state_change_t; -typedef switch_status_t (*switch_outgoing_channel_hook_t) (switch_core_session_t *, switch_caller_profile_t *, switch_core_session_t *); +typedef switch_status_t (*switch_outgoing_channel_hook_t) +(switch_core_session_t *, switch_caller_profile_t *, switch_core_session_t *, switch_originate_flag_t); typedef switch_status_t (*switch_receive_message_hook_t) (switch_core_session_t *, switch_core_session_message_t *); typedef switch_status_t (*switch_receive_event_hook_t) (switch_core_session_t *, switch_event_t *); typedef switch_status_t (*switch_read_frame_hook_t) (switch_core_session_t *, switch_frame_t **, int, switch_io_flag_t, int); diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index bbc05e087e..b6ce42ace2 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -355,6 +355,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses \param cid_name_override override the caller id name \param cid_num_override override the caller id number \param caller_profile_override override the entire calling caller profile + \param flags flags to pass \return SWITCH_STATUS_SUCCESS if bleg is a running session. \note bleg will be read locked which must be unlocked with switch_core_session_rwunlock() before losing scope */ @@ -364,7 +365,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess const char *bridgeto, uint32_t timelimit_sec, const switch_state_handler_table_t *table, - const char *cid_name_override, const char *cid_num_override, switch_caller_profile_t *caller_profile_override); + const char *cid_name_override, + const char *cid_num_override, + switch_caller_profile_t *caller_profile_override, + switch_originate_flag_t flags); /*! \brief Bridge Audio from one session to another diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 19d3f9b081..b5e4ed9a55 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -98,8 +98,8 @@ struct switch_stream_handle { struct switch_io_event_hooks; -typedef switch_call_cause_t -(*switch_io_outgoing_channel_t)(switch_core_session_t *, switch_caller_profile_t *, switch_core_session_t **, switch_memory_pool_t **); +typedef switch_call_cause_t (*switch_io_outgoing_channel_t) +(switch_core_session_t *, switch_caller_profile_t *, switch_core_session_t **, switch_memory_pool_t **, switch_originate_flag_t); typedef switch_status_t (*switch_io_read_frame_t) (switch_core_session_t *, switch_frame_t **, int, switch_io_flag_t, int); typedef switch_status_t (*switch_io_write_frame_t) (switch_core_session_t *, switch_frame_t *, int, switch_io_flag_t, int); typedef switch_status_t (*switch_io_kill_channel_t) (switch_core_session_t *, int); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 728dc93f17..3969165f0b 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -136,6 +136,12 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_BITS_PER_BYTE 8 typedef uint8_t switch_byte_t; +typedef enum { + SOF_NONE = 0, + SOF_NOBLOCK = (1 << 0), + SOF_FORKED_DIAL = (1 << 1) +} switch_originate_flag_t; + typedef enum { SPF_NONE = 0, SPF_ODD = (1 << 0), diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 6d7e6072ca..58e54b73fd 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1432,7 +1432,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) != SWITCH_STATUS_SUCCESS) { + if (switch_ivr_originate(NULL, &caller_session, &cause, aleg, timeout, NULL, cid_name, cid_num, NULL, SOF_NONE) != SWITCH_STATUS_SUCCESS) { if (machine) { stream->write_function(stream, "-ERR %s\n", switch_channel_cause2str(cause)); } else { diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index fba6002549..0796847e57 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -3630,7 +3630,7 @@ static 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); + status = switch_ivr_originate(NULL, &peer_session, cause, dialstr, 60, NULL, cid_name, cid_num, NULL, SOF_NONE); switch_safe_free(dialstr); if (status != SWITCH_STATUS_SUCCESS) { @@ -3667,7 +3667,7 @@ static switch_status_t conference_outcall(conference_obj_t * conference, /* establish an outbound call leg */ if (switch_ivr_originate(session, &peer_session, cause, bridgeto, timeout, &audio_bridge_peer_state_handlers, cid_name, cid_num, - NULL) != SWITCH_STATUS_SUCCESS) { + NULL, SOF_NONE) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create outgoing channel, cause: %s\n", switch_channel_cause2str(*cause)); if (caller_channel) { switch_channel_hangup(caller_channel, *cause); diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index f7ac9ee165..729ab57b1e 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1374,7 +1374,7 @@ SWITCH_STANDARD_APP(audio_bridge_function) } } - if (switch_ivr_originate(session, &peer_session, &cause, data, timelimit, NULL, NULL, NULL, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_ivr_originate(session, &peer_session, &cause, data, timelimit, NULL, NULL, NULL, NULL, SOF_NONE) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Originate Failed. Cause: %s\n", switch_channel_cause2str(cause)); /* no answer is *always* a reason to continue */ @@ -1449,19 +1449,23 @@ SWITCH_STANDARD_APP(audio_bridge_function) switch_endpoint_interface_t *user_endpoint_interface; static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool); + switch_core_session_t **new_session, + switch_memory_pool_t **pool, + switch_originate_flag_t flags); switch_io_routines_t user_io_routines = { /*.outgoing_channel */ user_outgoing_channel }; static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool) + switch_core_session_t **new_session, + switch_memory_pool_t **pool, + switch_originate_flag_t flags) { switch_xml_t x_domain = NULL, xml = NULL, x_user = NULL, x_param, x_params; char *user = NULL, *domain = NULL; const char *dest = NULL; - static switch_call_cause_t cause; + static switch_call_cause_t cause = SWITCH_CAUSE_SUCCESS; unsigned int timelimit = 60; switch_channel_t *new_channel = NULL; @@ -1472,7 +1476,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, } *domain++ = '\0'; - + if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, "as_channel=true") != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain); goto done; @@ -1510,7 +1514,8 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, const char *var; char *d_dest = NULL; switch_channel_t *channel; - + switch_originate_flag_t myflags = SOF_NONE; + channel = switch_core_session_get_channel(session); if ((var = switch_channel_get_variable(channel, "call_timeout"))) { timelimit = atoi(var); @@ -1521,7 +1526,11 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, d_dest = switch_channel_expand_variables(channel, dest); - if (switch_ivr_originate(session, new_session, &cause, d_dest, timelimit, NULL, NULL, NULL, NULL) == SWITCH_STATUS_SUCCESS) { + if ((flags & SOF_FORKED_DIAL)) { + myflags |= SOF_NOBLOCK; + } + + if (switch_ivr_originate(session, new_session, &cause, d_dest, timelimit, NULL, NULL, NULL, NULL, myflags) == SWITCH_STATUS_SUCCESS) { const char *context; switch_caller_profile_t *cp; diff --git a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c index afc041b5e4..c6fa3ead9a 100644 --- a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c +++ b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c @@ -312,15 +312,19 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt) /* fake chan_sip */ switch_endpoint_interface_t *sip_endpoint_interface; static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool); + switch_caller_profile_t *outbound_profile, + switch_core_session_t **new_session, + switch_memory_pool_t **pool, + switch_originate_flag_t flags); switch_io_routines_t sip_io_routines = { /*.outgoing_channel */ sip_outgoing_channel }; static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool) + switch_caller_profile_t *outbound_profile, + switch_core_session_t **new_session, + switch_memory_pool_t **pool, + switch_originate_flag_t flags) { const char *profile; @@ -334,7 +338,7 @@ static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, } outbound_profile->destination_number = switch_core_sprintf(outbound_profile->pool, "%s/%s", profile, outbound_profile->destination_number); - return switch_core_session_outgoing_channel(session, "sofia", outbound_profile, new_session, pool); + return switch_core_session_outgoing_channel(session, "sofia", outbound_profile, new_session, pool, SOF_NONE); } @@ -343,17 +347,21 @@ static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, /* fake chan_iax2 */ switch_endpoint_interface_t *iax2_endpoint_interface; static switch_call_cause_t iax2_outgoing_channel(switch_core_session_t *session, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool); + switch_caller_profile_t *outbound_profile, + switch_core_session_t **new_session, + switch_memory_pool_t **pool, + switch_originate_flag_t flags); switch_io_routines_t iax2_io_routines = { /*.outgoing_channel */ iax2_outgoing_channel }; static switch_call_cause_t iax2_outgoing_channel(switch_core_session_t *session, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool) + switch_caller_profile_t *outbound_profile, + switch_core_session_t **new_session, + switch_memory_pool_t **pool, + switch_originate_flag_t flags) { - return switch_core_session_outgoing_channel(session, "iax", outbound_profile, new_session, pool); + return switch_core_session_outgoing_channel(session, "iax", outbound_profile, new_session, pool, SOF_NONE); } diff --git a/src/mod/endpoints/mod_alsa/mod_alsa.c b/src/mod/endpoints/mod_alsa/mod_alsa.c index a2b9647410..e1b2bd1711 100644 --- a/src/mod/endpoints/mod_alsa/mod_alsa.c +++ b/src/mod/endpoints/mod_alsa/mod_alsa.c @@ -148,7 +148,7 @@ static switch_status_t channel_on_loopback(switch_core_session_t *session); static switch_status_t channel_on_transmit(switch_core_session_t *session); static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool); + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags); static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); @@ -778,7 +778,7 @@ static switch_loadable_module_interface_t channel_module_interface = { */ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool) + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags) { if ((*new_session = switch_core_session_request(&channel_endpoint_interface, pool)) != 0) { diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 97b79561f4..eec909d09b 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -206,7 +206,7 @@ static switch_status_t channel_on_loopback(switch_core_session_t *session); static switch_status_t channel_on_transmit(switch_core_session_t *session); static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool); + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags); static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); @@ -1616,7 +1616,7 @@ switch_io_routines_t dingaling_io_routines = { */ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool) + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags) { if ((*new_session = switch_core_session_request(dingaling_endpoint_interface, pool)) != 0) { struct private_object *tech_pvt; diff --git a/src/mod/endpoints/mod_iax/mod_iax.c b/src/mod/endpoints/mod_iax/mod_iax.c index f73e6dcdf6..650f59228d 100644 --- a/src/mod/endpoints/mod_iax/mod_iax.c +++ b/src/mod/endpoints/mod_iax/mod_iax.c @@ -421,7 +421,7 @@ static switch_status_t channel_on_loopback(switch_core_session_t *session); static switch_status_t channel_on_transmit(switch_core_session_t *session); static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool); + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags); static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); @@ -789,7 +789,7 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s */ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool) + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags) { if ((*new_session = switch_core_session_request(iax_endpoint_interface, pool)) != 0) { private_t *tech_pvt; diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index e382d73b12..1ad69c5581 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -145,7 +145,7 @@ static switch_status_t channel_on_loopback(switch_core_session_t *session); static switch_status_t channel_on_transmit(switch_core_session_t *session); static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool); + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags); static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); @@ -741,7 +741,7 @@ switch_io_routines_t portaudio_io_routines = { */ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool) + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags) { if ((*new_session = switch_core_session_request(portaudio_endpoint_interface, pool)) != 0) { diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index b209ea226a..6c0fc19659 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -56,7 +56,7 @@ static switch_status_t sofia_on_loopback(switch_core_session_t *session); static switch_status_t sofia_on_transmit(switch_core_session_t *session); static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session, - switch_memory_pool_t **pool); + switch_memory_pool_t **pool, switch_originate_flag_t flags); static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t sofia_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t sofia_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id); @@ -1490,7 +1490,7 @@ static switch_status_t sofia_manage(char *relative_oid, switch_management_action static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session, - switch_memory_pool_t **pool) + switch_memory_pool_t **pool, switch_originate_flag_t flags) { switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; switch_core_session_t *nsession; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index d0c84be93a..486a1e70bc 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1827,7 +1827,8 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, rep); if (switch_ivr_originate(a_session, - &tsession, &cause, exten, timeout, &noop_state_handler, NULL, NULL, NULL) != SWITCH_STATUS_SUCCESS) { + &tsession, &cause, exten, timeout, &noop_state_handler, NULL, NULL, NULL, SOF_NONE) + != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! [%s]\n", exten); nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag"), NUTAG_SUBSTATE(nua_substate_terminated), diff --git a/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c b/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c index b719bd33c6..38125acf0c 100644 --- a/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c +++ b/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c @@ -467,7 +467,7 @@ static switch_status_t wanpipe_on_hangup(switch_core_session_t *session); static switch_status_t wanpipe_on_loopback(switch_core_session_t *session); static switch_status_t wanpipe_on_transmit(switch_core_session_t *session); static switch_call_cause_t wanpipe_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool); + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags); static switch_status_t wanpipe_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t wanpipe_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, @@ -1003,7 +1003,7 @@ switch_state_handler_table_t wanpipe_state_handlers = { }; static switch_call_cause_t wanpipe_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool) + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags) { char *bchan = NULL; char name[128] = ""; diff --git a/src/mod/endpoints/mod_woomera/mod_woomera.c b/src/mod/endpoints/mod_woomera/mod_woomera.c index 3c1d9813c0..4ebe0b142b 100644 --- a/src/mod/endpoints/mod_woomera/mod_woomera.c +++ b/src/mod/endpoints/mod_woomera/mod_woomera.c @@ -175,7 +175,7 @@ static switch_status_t woomera_on_loopback(switch_core_session_t *session); static switch_status_t woomera_on_transmit(switch_core_session_t *session); static switch_call_cause_t woomera_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool); + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags); static switch_status_t woomera_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t woomera_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t woomera_kill_channel(switch_core_session_t *session, int sig); @@ -482,7 +482,7 @@ static switch_io_routines_t woomera_io_routines = { */ static switch_call_cause_t woomera_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool) + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags) { if ((*new_session = switch_core_session_request(woomera_endpoint_interface, pool)) != 0) { struct private_object *tech_pvt; diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c index 7b24ea9ca3..7f76b3dfc7 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c @@ -2709,7 +2709,8 @@ static JSBool session_originate(JSContext * cx, JSObject * obj, uintN argc, jsva caller_profile = switch_caller_profile_new(pool,username, dialplan, cid_name, cid_num, network_addr, ani, aniii, rdnis, modname, context, dest); - if (switch_ivr_originate(session, &peer_session, &jss->cause, dest, to ? atoi(to) : 60, NULL, NULL, NULL, caller_profile) != SWITCH_STATUS_SUCCESS) { + if (switch_ivr_originate(session, &peer_session, &jss->cause, dest, to ? atoi(to) : 60, NULL, NULL, NULL, caller_profile, SOF_NONE) + != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot Create Outgoing Channel! [%s]\n", dest); goto done; } diff --git a/src/switch_channel.c b/src/switch_channel.c index 1cddf64964..41f357df32 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -434,6 +434,34 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_variable(switch_channel_t *ch return SWITCH_STATUS_FALSE; } + +SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_partner(switch_channel_t *channel, const char *varname, const char *value) +{ + const char *uuid; + switch_assert(channel != NULL); + + if (!switch_strlen_zero(varname)) { + if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) { + switch_core_session_t *session; + switch_mutex_lock(channel->profile_mutex); + if ((session = switch_core_session_locate(uuid))) { + switch_channel_t *tchannel = switch_core_session_get_channel(session); + switch_mutex_lock(tchannel->profile_mutex); + switch_event_del_header(tchannel->variables, varname); + if (value) { + switch_event_add_header(tchannel->variables, SWITCH_STACK_BOTTOM, varname, "%s", value); + } + switch_mutex_unlock(tchannel->profile_mutex); + switch_core_session_rwunlock(session); + } + switch_mutex_unlock(channel->profile_mutex); + return SWITCH_STATUS_SUCCESS; + } + } + + return SWITCH_STATUS_FALSE; +} + SWITCH_DECLARE(int) switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flags) { switch_assert(channel != NULL); diff --git a/src/switch_core_session.c b/src/switch_core_session.c index b2c8495612..1cc88bc773 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -176,7 +176,9 @@ SWITCH_DECLARE(int) switch_core_session_get_stream_count(switch_core_session_t * SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_core_session_t *session, char *endpoint_name, switch_caller_profile_t *caller_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool) + switch_core_session_t **new_session, + switch_memory_pool_t **pool, + switch_originate_flag_t flags) { switch_io_event_hook_outgoing_channel_t *ptr; switch_status_t status = SWITCH_STATUS_FALSE; @@ -215,13 +217,13 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_ } } - if ((cause = endpoint_interface->io_routines->outgoing_channel(session, outgoing_profile, new_session, pool)) != SWITCH_CAUSE_SUCCESS) { + if ((cause = endpoint_interface->io_routines->outgoing_channel(session, outgoing_profile, new_session, pool, flags)) != SWITCH_CAUSE_SUCCESS) { return cause; } if (session) { for (ptr = session->event_hooks.outgoing_channel; ptr; ptr = ptr->next) { - if ((status = ptr->outgoing_channel(session, caller_profile, *new_session)) != SWITCH_STATUS_SUCCESS) { + if ((status = ptr->outgoing_channel(session, caller_profile, *new_session, flags)) != SWITCH_STATUS_SUCCESS) { break; } } diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index 5b6739f41c..038a0a2701 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -341,7 +341,8 @@ int CoreSession::originate(CoreSession *a_leg_session, NULL, NULL, NULL, - &caller_profile) != SWITCH_STATUS_SUCCESS) { + &caller_profile, + SOF_NONE) != 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 0e177e8acb..0111974bba 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -240,8 +240,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess const char *bridgeto, uint32_t timelimit_sec, const switch_state_handler_table_t *table, - const char *cid_name_override, const char *cid_num_override, switch_caller_profile_t *caller_profile_override) + const char *cid_name_override, + const char *cid_num_override, + switch_caller_profile_t *caller_profile_override, + switch_originate_flag_t flags) { + switch_originate_flag_t myflags = SOF_NONE; char *pipe_names[MAX_PEERS] = { 0 }; char *data = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; @@ -392,7 +396,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (caller_channel) { /* ringback is only useful when there is an originator */ - ringback_data = switch_channel_get_variable(caller_channel, "ringback"); + ringback_data = NULL; + + if (switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) { + ringback_data = switch_channel_get_variable(caller_channel, "transfer_ringback"); + } + + if (!ringback_data) { + ringback_data = switch_channel_get_variable(caller_channel, "ringback"); + } + switch_channel_set_variable(caller_channel, "originate_disposition", "failure"); } @@ -454,6 +467,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_assert(loop_data); 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_LOG, SWITCH_LOG_WARNING, "Only calling the first element in the list in this mode.\n"); + or_argc = 1; + } + if (caller_channel && or_argc > 1 && !ringback_data) { switch_channel_ring_ready(caller_channel); sent_ring = 1; @@ -486,6 +504,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess 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_LOG, SWITCH_LOG_WARNING, "Only calling the first elemnent in the list in this mode.\n"); + and_argc = 1; + } + if (caller_channel && !sent_ring && and_argc > 1 && !ringback_data) { switch_channel_ring_ready(caller_channel); sent_ring = 1; @@ -566,8 +589,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess peer_channels[i] = NULL; peer_sessions[i] = NULL; new_session = NULL; - - if ((reason = switch_core_session_outgoing_channel(session, chan_type, new_profile, &new_session, &pool)) != SWITCH_CAUSE_SUCCESS) { + + if (and_argc > 1 || or_argc > 1) { + myflags |= SOF_FORKED_DIAL; + } + if ((reason = switch_core_session_outgoing_channel(session, chan_type, new_profile, &new_session, &pool, myflags)) != SWITCH_CAUSE_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! cause: %s\n", switch_channel_cause2str(reason)); if (pool) { switch_core_destroy_memory_pool(&pool); @@ -623,12 +649,25 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_channel_add_state_handler(peer_channels[i], table); } + + if ((flags & SOF_NOBLOCK) && peer_sessions[i]) { + status = SWITCH_STATUS_SUCCESS; + *bleg = peer_sessions[i]; + *cause = SWITCH_CAUSE_SUCCESS; + goto outer_for; + } + + if (switch_core_session_running(peer_sessions[i])) { - switch_channel_set_state(peer_channels[i], CS_RING); + if (!(flags & SOF_NOBLOCK)) { + switch_channel_set_state(peer_channels[i], CS_RING); + } } else { switch_core_session_thread_launch(peer_sessions[i]); } - } + + + } time(&start); @@ -704,7 +743,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (switch_is_file_path(ringback_data)) { char *ext; - if ((ext = strrchr(ringback_data, '.'))) { + if (strrchr(ringback_data, '.') || strstr(ringback_data, SWITCH_URL_SEPARATOR)) { switch_core_session_set_read_codec(session, &write_codec); ext++; } else { diff --git a/src/switch_swig.c b/src/switch_swig.c index dad4919ad0..83e00fbfa5 100644 --- a/src/switch_swig.c +++ b/src/switch_swig.c @@ -240,7 +240,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) != SWITCH_STATUS_SUCCESS) { + if (switch_ivr_originate(session, &peer_session, &cause, bridgeto, timelimit, NULL, NULL, NULL, NULL, SOF_NONE) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel!\n"); switch_channel_hangup(caller_channel, SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL); return;