Merge pull request #896 in FS/freeswitch from ~ARMENB/freeswitch:feature/FS-9300-sending-100-trying-from-dialplan to master
* commit '6ed86abf9f6ab1116a39b28c651dec1d4f6cf89f': FS-9300: Add support for disabling sofia's 100 Trying via configuration, and sending 100 Trying from dialplan
This commit is contained in:
commit
da4b7f31f1
|
@ -828,5 +828,13 @@
|
|||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="acknowledge_call">
|
||||
<condition field="destination_number" expression="^(.*)$">
|
||||
<action application="acknowledge_call"/>
|
||||
<action application="ring_ready"/>
|
||||
<action application="playback" data="$${hold_music}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
</context>
|
||||
</include>
|
||||
|
|
|
@ -418,5 +418,9 @@
|
|||
-->
|
||||
<!--<param name="renegotiate-codec-on-hold" value="true"/>-->
|
||||
|
||||
<!-- By default mod_sofia will send "100 Trying" in response to a SIP INVITE. Set this to false if
|
||||
you want to turn off this behavior and manually send the "100 Trying" via the acknowledge_call application.
|
||||
-->
|
||||
<!--<param name="auto-invite-100" value="false"/>-->
|
||||
</settings>
|
||||
</profile>
|
||||
|
|
|
@ -6460,8 +6460,14 @@ static int nta_incoming_response_headers(nta_incoming_t *irq,
|
|||
clone = 1, sip->sip_call_id = sip_call_id_copy(home, irq->irq_call_id);
|
||||
if (!sip->sip_cseq)
|
||||
clone = 1, sip->sip_cseq = sip_cseq_copy(home, irq->irq_cseq);
|
||||
if (!sip->sip_via)
|
||||
clone = 1, sip->sip_via = sip_via_copy(home, irq->irq_via);
|
||||
if (!sip->sip_via) {
|
||||
clone = 1;
|
||||
/* 100 responses are not forwarded by proxies, so only include the topmost Via header */
|
||||
if (sip->sip_status && sip->sip_status->st_status == 100)
|
||||
sip->sip_via = (sip_via_t *)msg_header_copy_one(home, (msg_header_t const *)irq->irq_via);
|
||||
else
|
||||
sip->sip_via = sip_via_copy(home, irq->irq_via);
|
||||
}
|
||||
|
||||
if (clone)
|
||||
msg_set_parent(msg, (msg_t *)irq->irq_home);
|
||||
|
@ -6530,7 +6536,7 @@ int nta_incoming_complete_response(nta_incoming_t *irq,
|
|||
if (sip_to_tag(home, sip->sip_to, irq->irq_tag) < 0)
|
||||
return -1;
|
||||
|
||||
if (status < 300 && !sip->sip_record_route && irq->irq_record_route)
|
||||
if (status > 100 && status < 300 && !sip->sip_record_route && irq->irq_record_route)
|
||||
if (sip_add_dup(msg, sip, (sip_header_t *)irq->irq_record_route) < 0)
|
||||
return -1;
|
||||
|
||||
|
|
|
@ -173,6 +173,8 @@ int nua_stack_set_defaults(nua_handle_t *nh,
|
|||
|
||||
NHP_SET(nhp, keepalive, 120000);
|
||||
|
||||
NHP_SET(nhp, auto_invite_100, 1);
|
||||
|
||||
NHP_SET(nhp, appl_method,
|
||||
sip_allow_make(home, "INVITE, REGISTER, PUBLISH, SUBSCRIBE"));
|
||||
|
||||
|
@ -1013,6 +1015,10 @@ static int nhp_set_tags(su_home_t *home,
|
|||
else if (tag == ntatag_default_proxy) {
|
||||
NHP_SET_STR_BY_URL(nhp, url_string_t, proxy, value);
|
||||
}
|
||||
/* NUTAG_AUTO_INVITE_100() */
|
||||
else if (tag == nutag_auto_invite_100) {
|
||||
NHP_SET(nhp, auto_invite_100, value != 0);
|
||||
}
|
||||
/* NUTAG_DETECT_NETWORK_UPDATES(detect_network_updates) */
|
||||
else if (ngp && tag == nutag_detect_network_updates) {
|
||||
int detector = (int)value;
|
||||
|
|
|
@ -115,6 +115,9 @@ struct nua_handle_preferences
|
|||
/** Enable Retry-After */
|
||||
unsigned nhp_retry_after_enable:1;
|
||||
|
||||
/** Enable/Disable automatic 100 Trying when receiving INVITE */
|
||||
unsigned nhp_auto_invite_100:1;
|
||||
|
||||
unsigned:0;
|
||||
|
||||
/* Default lifetime for implicit subscriptions created by REFER */
|
||||
|
@ -215,6 +218,7 @@ struct nua_handle_preferences
|
|||
unsigned nhb_proxy:1;
|
||||
unsigned nhb_timer_autorequire:1;
|
||||
unsigned nhb_retry_after_enable:1;
|
||||
unsigned nhb_auto_invite_100:1;
|
||||
unsigned :0;
|
||||
} set_bits;
|
||||
unsigned set_unsigned[2];
|
||||
|
|
|
@ -262,7 +262,8 @@ int nua_stack_process_request(nua_handle_t *nh,
|
|||
|
||||
if (sr->sr_status <= 100) {
|
||||
SR_STATUS1(sr, SIP_100_TRYING);
|
||||
if (method == sip_method_invite || sip->sip_timestamp) {
|
||||
if ((method == sip_method_invite && nh->nh_prefs->nhp_auto_invite_100) ||
|
||||
sip->sip_timestamp) {
|
||||
nta_incoming_treply(irq, SIP_100_TRYING,
|
||||
SIPTAG_USER_AGENT_STR(user_agent),
|
||||
TAG_END());
|
||||
|
@ -459,7 +460,12 @@ nua_stack_respond(nua_t *nua, nua_handle_t *nh,
|
|||
|
||||
nua_server_params(sr, tags);
|
||||
nua_server_respond(sr, tags);
|
||||
nua_server_report(sr);
|
||||
|
||||
if (!(sr->sr_method == sip_method_invite && status == 100)) {
|
||||
/* Since we don't change state, do not notify application when
|
||||
we send 100 Trying for INVITE */
|
||||
nua_server_report(sr);
|
||||
}
|
||||
}
|
||||
|
||||
int nua_server_params(nua_server_request_t *sr, tagi_t const *tags)
|
||||
|
@ -528,6 +534,13 @@ int nua_server_respond(nua_server_request_t *sr, tagi_t const *tags)
|
|||
goto internal_error;
|
||||
}
|
||||
|
||||
if (sr->sr_status == 100) {
|
||||
return nta_incoming_treply(sr->sr_irq, SIP_100_TRYING,
|
||||
SIPTAG_USER_AGENT_STR(NH_PGET(nh, user_agent)),
|
||||
TAG_END());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sr->sr_status < 200) {
|
||||
next.msg = nta_incoming_create_response(sr->sr_irq, 0, NULL);
|
||||
next.sip = sip_object(next.msg);
|
||||
|
|
|
@ -2796,6 +2796,13 @@ tag_typedef_t nutag_auth_cache = INTTAG_TYPEDEF(auth_cache);
|
|||
* Reference tag for NUTAG_AUTH_CACHE().
|
||||
*/
|
||||
|
||||
/**@def NUTAG_AUTO_INVITE_100(x)
|
||||
*/
|
||||
tag_typedef_t nutag_auto_invite_100 = INTTAG_TYPEDEF(auto_invite_100);
|
||||
|
||||
/**@def NUTAG_AUTO_INVITE_100(x)
|
||||
* Reference tag for NUTAG_AUTO_INVITE_100().
|
||||
*/
|
||||
|
||||
/**@def NUTAG_DETECT_NETWORK_UPDATES(x)
|
||||
*
|
||||
|
|
|
@ -611,6 +611,13 @@ SOFIAPUBVAR tag_typedef_t nutag_shutdown_events;
|
|||
nutag_shutdown_events_ref, tag_bool_vr(&(x))
|
||||
SOFIAPUBVAR tag_typedef_t nutag_shutdown_events_ref;
|
||||
|
||||
#define NUTAG_AUTO_INVITE_100(x) \
|
||||
nutag_auto_invite_100, tag_bool_v(x)
|
||||
SOFIAPUBVAR tag_typedef_t nutag_auto_invite_100;
|
||||
#define NUTAG_AUTO_INVITE_100_REF(x) \
|
||||
nutag_auto_invite_100_ref, tag_bool_vr(&(x))
|
||||
SOFIAPUBVAR tag_typedef_t nutag_auto_invite_100_ref;
|
||||
|
||||
/* Pass nua handle as tagged argument */
|
||||
#if SU_INLINE_TAG_CAST
|
||||
su_inline tag_value_t nutag_handle_v(nua_handle_t *v) { return (tag_value_t)v; }
|
||||
|
|
|
@ -447,6 +447,10 @@ SWITCH_DECLARE(void) switch_channel_check_zrtp(switch_channel_t *channel);
|
|||
*/
|
||||
#define switch_channel_mark_pre_answered(channel) switch_channel_perform_mark_pre_answered(channel, __FILE__, __SWITCH_FUNC__, __LINE__)
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_perform_acknowledge_call(switch_channel_t *channel,
|
||||
const char *file, const char *func, int line);
|
||||
#define switch_channel_acknowledge_call(channel) switch_channel_perform_acknowledge_call(channel, __FILE__, __SWITCH_FUNC__, __LINE__)
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_perform_ring_ready_value(switch_channel_t *channel,
|
||||
switch_ring_ready_t rv,
|
||||
const char *file, const char *func, int line);
|
||||
|
|
|
@ -1052,6 +1052,7 @@ typedef enum {
|
|||
SWITCH_MESSAGE_REDIRECT_AUDIO,
|
||||
SWITCH_MESSAGE_TRANSMIT_TEXT,
|
||||
SWITCH_MESSAGE_INDICATE_ANSWER,
|
||||
SWITCH_MESSAGE_INDICATE_ACKNOWLEDGE_CALL,
|
||||
SWITCH_MESSAGE_INDICATE_PROGRESS,
|
||||
SWITCH_MESSAGE_INDICATE_BRIDGE,
|
||||
SWITCH_MESSAGE_INDICATE_UNBRIDGE,
|
||||
|
|
|
@ -1048,6 +1048,11 @@ SWITCH_STANDARD_APP(capture_text_function)
|
|||
switch_ivr_capture_text(session, switch_true((char *)data));
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_APP(acknowledge_call_function)
|
||||
{
|
||||
switch_channel_acknowledge_call(switch_core_session_get_channel(session));
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_APP(ring_ready_function)
|
||||
{
|
||||
if (!zstr(data)) {
|
||||
|
@ -6298,6 +6303,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
|||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "capture_text", "capture text", "capture text", capture_text_function, "", SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "acknowledge_call", "Indicate Call Acknowledged", "Indicate Call Acknowledged on a channel.", acknowledge_call_function, "", SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "ring_ready", "Indicate Ring_Ready", "Indicate Ring_Ready on a channel.", ring_ready_function, "", SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "remove_bugs", "Remove media bugs", "Remove all media bugs from a channel.", remove_bugs_function, "[<function>]", SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "break", "Break", "Set the break flag.", break_function, "", SAF_SUPPORT_NOMEDIA);
|
||||
|
|
|
@ -55,6 +55,7 @@ static switch_status_t sofia_on_init(switch_core_session_t *session);
|
|||
|
||||
static switch_status_t sofia_on_exchange_media(switch_core_session_t *session);
|
||||
static switch_status_t sofia_on_soft_execute(switch_core_session_t *session);
|
||||
static switch_status_t sofia_acknowledge_call(switch_core_session_t *session);
|
||||
static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
|
||||
switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session,
|
||||
switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
|
||||
|
@ -137,6 +138,14 @@ static switch_status_t sofia_on_routing(switch_core_session_t *session)
|
|||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_assert(tech_pvt != NULL);
|
||||
|
||||
if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_INVITE_100) &&
|
||||
!switch_channel_test_flag(channel, CF_ANSWERED) &&
|
||||
switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
if (sofia_acknowledge_call(session) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Call appears to be already acknowledged\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!sofia_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) {
|
||||
sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
switch_channel_clear_flag(channel, CF_LEG_HOLDING);
|
||||
|
@ -642,6 +651,19 @@ static switch_status_t sofia_on_soft_execute(switch_core_session_t *session)
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t sofia_acknowledge_call(switch_core_session_t *session)
|
||||
{
|
||||
struct private_object *tech_pvt = switch_core_session_get_private(session);
|
||||
|
||||
if (!tech_pvt->sent_100) {
|
||||
nua_respond(tech_pvt->nh, SIP_100_TRYING, TAG_END());
|
||||
tech_pvt->sent_100 = 1;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
||||
{
|
||||
private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
|
||||
|
@ -656,6 +678,10 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
|||
char *sticky = NULL;
|
||||
const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
|
||||
|
||||
if(sofia_acknowledge_call(session) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Dialplan did not acknowledge_call; sent 100 Trying");
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_CONFERENCE) && !switch_stristr(";isfocus", tech_pvt->reply_contact)) {
|
||||
tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s;isfocus", tech_pvt->reply_contact);
|
||||
}
|
||||
|
@ -2176,6 +2202,12 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
|||
}
|
||||
}
|
||||
|
||||
/* Dialplan should really use acknowledge_call application instead of respond application to send 100 */
|
||||
if (code == 100) {
|
||||
status = sofia_acknowledge_call(session);
|
||||
goto end_lock;
|
||||
}
|
||||
|
||||
if (tech_pvt->proxy_refer_uuid) {
|
||||
if (tech_pvt->proxy_refer_msg) {
|
||||
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
|
||||
|
@ -2295,10 +2327,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
|||
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
|
||||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_ACKNOWLEDGE_CALL:
|
||||
status = sofia_acknowledge_call(session);
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_RINGING:
|
||||
{
|
||||
switch_ring_ready_t ring_ready_val = msg->numeric_arg;
|
||||
|
||||
if(sofia_acknowledge_call(session) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Dialplan did not acknowledge_call; sent 100 Trying");
|
||||
}
|
||||
|
||||
if (!switch_channel_test_flag(channel, CF_RING_READY) && !sofia_test_flag(tech_pvt, TFLAG_BYE) &&
|
||||
!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(channel, CF_ANSWERED)) {
|
||||
char *extra_header = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX);
|
||||
|
@ -2360,6 +2399,10 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
|||
int send_sip_code = 183;
|
||||
const char * p_send_sip_msg = sip_183_Session_progress;
|
||||
|
||||
if(sofia_acknowledge_call(session) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Dialplan did not acknowledge_call; sent 100 Trying");
|
||||
}
|
||||
|
||||
b_sdp = switch_channel_get_variable(channel, SWITCH_B_SDP_VARIABLE);
|
||||
is_proxy = (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA));
|
||||
is_3pcc_proxy = (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY) && sofia_test_flag(tech_pvt, TFLAG_3PCC));
|
||||
|
|
|
@ -307,6 +307,7 @@ typedef enum {
|
|||
PFLAG_PROXY_INFO,
|
||||
PFLAG_PROXY_MESSAGE,
|
||||
PFLAG_FIRE_BYE_RESPONSE_EVENTS,
|
||||
PFLAG_AUTO_INVITE_100,
|
||||
|
||||
/* No new flags below this line */
|
||||
PFLAG_MAX
|
||||
|
@ -839,6 +840,7 @@ struct private_object {
|
|||
sip_contact_t *contact;
|
||||
int q850_cause;
|
||||
int got_bye;
|
||||
int sent_100;
|
||||
nua_event_t want_event;
|
||||
switch_rtp_bug_flag_t rtp_bugs;
|
||||
char *user_via;
|
||||
|
|
|
@ -3155,6 +3155,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
|
|||
NTATAG_TCP_RPORT(0),
|
||||
NTATAG_TLS_RPORT(0),
|
||||
NUTAG_RETRY_AFTER_ENABLE(0),
|
||||
NUTAG_AUTO_INVITE_100(0),
|
||||
TAG_IF(!strchr(profile->sipip, ':'),
|
||||
SOATAG_AF(SOA_AF_IP4_ONLY)),
|
||||
TAG_IF(strchr(profile->sipip, ':'),
|
||||
|
@ -4517,6 +4518,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
|||
}
|
||||
|
||||
profile->tls_verify_policy = TPTLS_VERIFY_NONE;
|
||||
sofia_set_pflag(profile, PFLAG_AUTO_INVITE_100);
|
||||
/* lib default */
|
||||
profile->tls_verify_depth = 2;
|
||||
|
||||
|
@ -5326,6 +5328,12 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
|||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_SECURE);
|
||||
}
|
||||
} else if (!strcasecmp(var, "auto-invite-100")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_AUTO_INVITE_100);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_AUTO_INVITE_100);
|
||||
}
|
||||
} else {
|
||||
found = 0;
|
||||
}
|
||||
|
@ -9833,6 +9841,8 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
|
|||
switch_channel_t *channel = NULL;
|
||||
private_object_t *tech_pvt = NULL;
|
||||
|
||||
nua_respond(nh, SIP_100_TRYING, TAG_END());
|
||||
|
||||
if (session) {
|
||||
channel = switch_core_session_get_channel(session);
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
|
|
|
@ -3305,6 +3305,13 @@ static switch_status_t send_ind(switch_channel_t *channel, switch_core_session_m
|
|||
return switch_core_session_perform_receive_message(channel->session, &msg, file, func, line);
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_perform_acknowledge_call(switch_channel_t *channel,
|
||||
const char *file, const char *func, int line)
|
||||
{
|
||||
send_ind(channel, SWITCH_MESSAGE_INDICATE_ACKNOWLEDGE_CALL, file, func, line);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_ring_ready_value(switch_channel_t *channel,
|
||||
switch_ring_ready_t rv,
|
||||
|
|
Loading…
Reference in New Issue