Revision
15159
Author
anthm
Date
2009-10-14 14:26:10 -0500 (Wed, 14 Oct 2009)

Log Message

delay update till after media has been confirmed to prevent SOA race in sip

Modified Paths

Diff

Modified: freeswitch/trunk/src/include/switch_channel.h (15158 => 15159)


--- freeswitch/trunk/src/include/switch_channel.h	2009-10-14 14:58:45 UTC (rev 15158)
+++ freeswitch/trunk/src/include/switch_channel.h	2009-10-14 19:26:10 UTC (rev 15159)
@@ -80,6 +80,7 @@
 #define switch_channel_media_ready(_channel) switch_channel_test_ready(_channel, SWITCH_TRUE)
 #define switch_channel_up(_channel) (switch_channel_get_state(_channel) < CS_HANGUP)
 #define switch_channel_down(_channel) (switch_channel_get_state(_channel) >= CS_HANGUP)
+#define switch_channel_media_ack(_channel) (!switch_channel_test_cap(_channel, CC_MEDIA_ACK) || switch_channel_test_flag(_channel, CF_MEDIA_ACK))
 
 SWITCH_DECLARE(void) switch_channel_wait_for_state(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state);
 SWITCH_DECLARE(void) switch_channel_wait_for_state_timeout(switch_channel_t *other_channel, switch_channel_state_t want_state, uint32_t timeout);
@@ -297,6 +298,10 @@
 SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flag);
 SWITCH_DECLARE(void) switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag);
 
+SWITCH_DECLARE(void) switch_channel_set_cap(switch_channel_t *channel, switch_channel_cap_t cap);
+SWITCH_DECLARE(void) switch_channel_clear_cap(switch_channel_t *channel, switch_channel_cap_t cap);
+SWITCH_DECLARE(uint32_t) switch_channel_test_cap(switch_channel_t *channel, switch_channel_cap_t cap);
+
 /*!
   \brief Set given flag(s) on a given channel's bridge partner
   \param channel channel to derive the partner channel to set flag on

Modified: freeswitch/trunk/src/include/switch_types.h (15158 => 15159)


--- freeswitch/trunk/src/include/switch_types.h	2009-10-14 14:58:45 UTC (rev 15158)
+++ freeswitch/trunk/src/include/switch_types.h	2009-10-14 19:26:10 UTC (rev 15159)
@@ -867,6 +867,12 @@
  */
 
 typedef enum {
+	CC_MEDIA_ACK = 1,
+	/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
+	CC_FLAG_MAX
+} switch_channel_cap_t;
+
+typedef enum {
 	CF_ANSWERED = 1,
 	CF_OUTBOUND,
 	CF_EARLY_MEDIA,
@@ -906,6 +912,7 @@
 	CF_TIMESTAMP_SET,
 	CF_ORIGINATOR,
 	CF_XFER_ZOMBIE,
+	CF_MEDIA_ACK,
 	/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
 	CF_FLAG_MAX
 } switch_channel_flag_t;

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (15158 => 15159)


--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c	2009-10-14 14:58:45 UTC (rev 15158)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c	2009-10-14 19:26:10 UTC (rev 15159)
@@ -1289,43 +1289,45 @@
 					number = tech_pvt->caller_profile->destination_number;
 				}
 
-				if (switch_strlen_zero(tech_pvt->last_sent_callee_id_name) || strcmp(tech_pvt->last_sent_callee_id_name, name) ||
-					switch_strlen_zero(tech_pvt->last_sent_callee_id_number) || strcmp(tech_pvt->last_sent_callee_id_number, number)) {
+				if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
+					switch_channel_set_variable(channel, "sip_callee_id_name", name);
+					switch_channel_set_variable(channel, "sip_callee_id_number", number);
+				} else {
+					if (switch_strlen_zero(tech_pvt->last_sent_callee_id_name) || strcmp(tech_pvt->last_sent_callee_id_name, name) ||
+						switch_strlen_zero(tech_pvt->last_sent_callee_id_number) || strcmp(tech_pvt->last_sent_callee_id_number, number)) {
 					
-					if (ua && switch_stristr("snom", ua)) {
-						snprintf(message, sizeof(message), "From:\r\nTo: \"%s\" %s\r\n", name, number);
-						nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
-								 TAG_IF(!switch_strlen_zero(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
-								 SIPTAG_PAYLOAD_STR(message), TAG_END());
-					} else if ((ua && (switch_stristr("polycom", ua) ||
-									   switch_stristr("UPDATE", tech_pvt->x_actually_support_remote)))) {
-						snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", name, number);
-						nua_update(tech_pvt->nh,
-								   TAG_IF(!switch_strlen_zero_buf(message), SIPTAG_HEADER_STR(message)),
-								   TAG_IF(!switch_strlen_zero(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
-								   TAG_END());
-					}
+						if (ua && switch_stristr("snom", ua)) {
+							snprintf(message, sizeof(message), "From:\r\nTo: \"%s\" %s\r\n", name, number);
+							nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+									 TAG_IF(!switch_strlen_zero(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
+									 SIPTAG_PAYLOAD_STR(message), TAG_END());
+						} else if ((ua && (switch_stristr("polycom", ua) ||
+										   switch_stristr("UPDATE", tech_pvt->x_actually_support_remote)))) {
+							snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", name, number);
+							nua_update(tech_pvt->nh,
+									   TAG_IF(!switch_strlen_zero_buf(message), SIPTAG_HEADER_STR(message)),
+									   TAG_IF(!switch_strlen_zero(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
+									   TAG_END());
+						}
 
-					tech_pvt->last_sent_callee_id_name = switch_core_session_strdup(tech_pvt->session, name);
-					tech_pvt->last_sent_callee_id_number = switch_core_session_strdup(tech_pvt->session, number);
+						tech_pvt->last_sent_callee_id_name = switch_core_session_strdup(tech_pvt->session, name);
+						tech_pvt->last_sent_callee_id_number = switch_core_session_strdup(tech_pvt->session, number);
 					
-					if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE) == SWITCH_STATUS_SUCCESS) {
-						const char *uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE);
-						switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Direction", "SEND");
-						switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Callee-Name", name);
-						switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Callee-Number", number);
-						if (uuid) {
-							switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridged-To", uuid);
+						if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE) == SWITCH_STATUS_SUCCESS) {
+							const char *uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE);
+							switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Direction", "SEND");
+							switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Callee-Name", name);
+							switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Callee-Number", number);
+							if (uuid) {
+								switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridged-To", uuid);
+							}
+							switch_channel_event_set_data(channel, event);
+							switch_event_fire(&event);
 						}
-						switch_channel_event_set_data(channel, event);
-						switch_event_fire(&event);
+					} else {
+						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Not sending same id again \"%s\" <%s>\n", name, number);
 					}
-				} else {
-					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Not sending same id again \"%s\" <%s>\n", name, number);
 				}
-
-
-
 			}
 
 			switch_safe_free(arg);

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c (15158 => 15159)


--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	2009-10-14 14:58:45 UTC (rev 15158)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	2009-10-14 19:26:10 UTC (rev 15159)
@@ -603,12 +603,15 @@
 	case nua_r_cancel:
 	case nua_i_error:
 	case nua_i_active:
-	case nua_i_ack:
 	case nua_i_terminated:
 	case nua_r_set_params:
 	case nua_i_prack:
 	case nua_r_prack:
 		break;
+	case nua_i_ack:
+	case nua_r_ack:
+		if (channel) switch_channel_set_flag(channel, CF_MEDIA_ACK);
+		break;
 	case nua_r_shutdown:
 		if (status >= 200) su_root_break(profile->s_root);
 		break;
@@ -1021,6 +1024,7 @@
 				   NUTAG_APPL_METHOD("REGISTER"),
 				   NUTAG_APPL_METHOD("NOTIFY"),
 				   NUTAG_APPL_METHOD("INFO"),
+				   NUTAG_APPL_METHOD("ACK"),
 #ifdef MANUAL_BYE
 				   NUTAG_APPL_METHOD("BYE"),
 #endif
@@ -3109,11 +3113,12 @@
 			caller_profile->network_addr = switch_core_strdup(caller_profile->pool, network_ip);
 		}
 
-		switch_channel_clear_flag(channel, CF_REQ_MEDIA);
-		
 		if ((status == 180 || status == 183 || status == 200)) { 
 			const char *x_actually_support;
 
+			switch_channel_set_flag(channel, CF_MEDIA_ACK);
+			switch_channel_clear_flag(channel, CF_REQ_MEDIA);
+
 			if ((x_actually_support = sofia_glue_get_unknown_header(sip, "X-Actually-Support"))) {
 				tech_pvt->x_actually_support_remote = switch_core_session_strdup(session, x_actually_support);
 			}

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c (15158 => 15159)


--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c	2009-10-14 14:58:45 UTC (rev 15158)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c	2009-10-14 19:26:10 UTC (rev 15159)
@@ -521,6 +521,8 @@
 
 	tech_pvt->session = session;
 	tech_pvt->channel = switch_core_session_get_channel(session);
+	switch_channel_set_cap(tech_pvt->channel, CC_MEDIA_ACK);
+	
 	switch_core_session_set_private(session, tech_pvt);
 
 	switch_snprintf(name, sizeof(name), "sofia/%s/%s", profile->name, channame);

Modified: freeswitch/trunk/src/switch_channel.c (15158 => 15159)


--- freeswitch/trunk/src/switch_channel.c	2009-10-14 14:58:45 UTC (rev 15158)
+++ freeswitch/trunk/src/switch_channel.c	2009-10-14 19:26:10 UTC (rev 15159)
@@ -1,4 +1,3 @@
-
 /* 
  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
  * Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
@@ -120,6 +119,7 @@
 	switch_channel_state_t state;
 	switch_channel_state_t running_state;
 	uint32_t flags[CF_FLAG_MAX];
+	uint32_t caps[CC_FLAG_MAX];
 	uint8_t state_flags[CF_FLAG_MAX];
 	uint32_t private_flags;
 	uint32_t app_flags;
@@ -841,6 +841,33 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
+
+SWITCH_DECLARE(void) switch_channel_set_cap(switch_channel_t *channel, switch_channel_cap_t cap)
+{
+	switch_assert(channel);
+	switch_assert(channel->flag_mutex);
+
+	switch_mutex_lock(channel->flag_mutex);
+	channel->caps[cap] = 1;
+	switch_mutex_unlock(channel->flag_mutex);
+}
+
+SWITCH_DECLARE(void) switch_channel_clear_cap(switch_channel_t *channel, switch_channel_cap_t cap)
+{
+	switch_assert(channel != NULL);
+	switch_assert(channel->flag_mutex);
+
+	switch_mutex_lock(channel->flag_mutex);
+	channel->caps[cap] = 0;
+	switch_mutex_unlock(channel->flag_mutex);
+}
+
+SWITCH_DECLARE(uint32_t) switch_channel_test_cap(switch_channel_t *channel, switch_channel_cap_t cap)
+{
+	switch_assert(channel != NULL);
+	return channel->caps[cap] ? 1 : 0;
+}
+
 SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flag)
 {
 	switch_assert(channel);

Modified: freeswitch/trunk/src/switch_ivr_bridge.c (15158 => 15159)


--- freeswitch/trunk/src/switch_ivr_bridge.c	2009-10-14 14:58:45 UTC (rev 15158)
+++ freeswitch/trunk/src/switch_ivr_bridge.c	2009-10-14 19:26:10 UTC (rev 15159)
@@ -161,7 +161,7 @@
 	const char *silence_var, *var;
 	int silence_val = 0, bypass_media_after_bridge = 0;
 	const char *bridge_answer_timeout = NULL;
-	int answer_timeout, sent_update = -50;
+	int answer_timeout, sent_update = 0;
 	time_t answer_limit = 0;
 	
 
@@ -184,6 +184,7 @@
 	chan_b = switch_core_session_get_channel(session_b);
 
 	ans_a = switch_channel_test_flag(chan_a, CF_ANSWERED);
+
 	if ((originator = switch_channel_test_flag(chan_a, CF_BRIDGE_ORIGINATOR))) {
 		pre_b = switch_channel_test_flag(chan_a, CF_EARLY_MEDIA);
 		ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED);
@@ -397,12 +398,9 @@
 			}
 		}
 		
-
-		if (originator && sent_update < 0 && ans_a && ans_b) {
-			if (!++sent_update) {
-				switch_ivr_bridge_display(session_a, session_b);
-				sent_update = 1;
-			}
+		if (originator && !sent_update && ans_a && ans_b && switch_channel_media_ack(chan_a) && switch_channel_media_ack(chan_b)) {
+			switch_ivr_bridge_display(session_a, session_b);
+			sent_update = 1;
 		}
 
 #ifndef SWITCH_VIDEO_IN_THREADS