From 0a8e115b980d4fdea41f1da4c5b715348760a4f3 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Fri, 15 Apr 2016 19:35:00 -0500
Subject: [PATCH] FS-9060: [mod_sofia] correct issues with hold and broken soa
 negotiations after performing a bypass media reinvite

---
 src/mod/endpoints/mod_sofia/mod_sofia.c  | 32 ++++++++++++------------
 src/mod/endpoints/mod_sofia/mod_sofia.h  |  2 ++
 src/mod/endpoints/mod_sofia/sofia.c      |  4 ++-
 src/mod/endpoints/mod_sofia/sofia_glue.c | 18 +++++++++++++
 4 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 3bf5b4968d..bc20ac2968 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -1510,10 +1510,13 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
 
 			switch_channel_clear_flag(tech_pvt->channel, CF_MEDIA_ACK);
 			switch_channel_set_flag(tech_pvt->channel, CF_REQ_MEDIA);
-			
-			nua_invite(tech_pvt->nh, NUTAG_MEDIA_ENABLE(0),
+
+			sofia_glue_clear_soa(session, SWITCH_TRUE);
+
+			nua_invite(tech_pvt->nh,
+					   NUTAG_MEDIA_ENABLE(0),
 					   TAG_IF(msg->string_arg, SIPTAG_CONTENT_TYPE_STR("application/sdp")), 
-					   TAG_IF(msg->string_arg, SIPTAG_PAYLOAD_STR(msg->string_arg)), 
+					   SIPTAG_PAYLOAD_STR(msg->string_arg),
 					   TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
 			
 			switch_safe_free(extra_headers);
@@ -1523,10 +1526,13 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
 		{
 			char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX);
 
+			sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
+
 			switch_channel_clear_flag(tech_pvt->channel, CF_MEDIA_ACK);
 			switch_channel_clear_flag(tech_pvt->channel, CF_MEDIA_SET);
 			switch_channel_set_flag(tech_pvt->channel, CF_REQ_MEDIA);
 
+			sofia_glue_clear_soa(session, SWITCH_TRUE);
 
 			nua_invite(tech_pvt->nh, NUTAG_MEDIA_ENABLE(0), SIPTAG_PAYLOAD_STR(""), 
 					   TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
@@ -2078,19 +2084,13 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
 								switch_core_media_patch_sdp(tech_pvt->session);
 								switch_core_media_proxy_remote_addr(session, NULL);
 							}
-							if (sofia_use_soa(tech_pvt)) {
-								nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-											SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
-											SOATAG_REUSE_REJECTED(1),
-											SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
-											TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
-							} else {
-								nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-											NUTAG_MEDIA_ENABLE(0),
-											SIPTAG_CONTENT_TYPE_STR("application/sdp"),
-											SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
-											TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
-							}
+
+							nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
+										NUTAG_MEDIA_ENABLE(0),
+										SIPTAG_CONTENT_TYPE_STR("application/sdp"),
+										SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
+										TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
+
 							if (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY) && sofia_test_flag(tech_pvt, TFLAG_3PCC)) {
 								/* Unlock the session signal to allow the ack to make it in */
 								// Maybe we should timeout?
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h
index 19ce2d711a..9a4dca3147 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.h
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.h
@@ -1205,6 +1205,8 @@ void sofia_reg_check_socket(sofia_profile_t *profile, const char *call_id, const
 void sofia_reg_close_handles(sofia_profile_t *profile);
 
 void write_csta_xml_chunk(switch_event_t *event, switch_stream_handle_t stream, const char *csta_event, char *fwd_type);
+void sofia_glue_clear_soa(switch_core_session_t *session, switch_bool_t partner);
+
 /* For Emacs:
  * Local Variables:
  * mode:c
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index f86b79fd1a..f2f458ffec 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -7375,11 +7375,13 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
 
 			nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
 			goto done;
-		} else if (r_sdp && !sofia_use_soa(tech_pvt)) {
+			
+			/* } else if (0 && r_sdp && !sofia_use_soa(tech_pvt)) {
 			nua_respond(tech_pvt->nh, SIP_200_OK,
 						NUTAG_MEDIA_ENABLE(0),
 						SIPTAG_CONTACT_STR(tech_pvt->profile->url),
 						SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
+			*/
 		} else {
 			ss_state = nua_callstate_completed;
 			goto state_process;
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index 010098f07c..eaad00a2a1 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -3087,6 +3087,24 @@ void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event)
 	*event = NULL;
 }
 
+void sofia_glue_clear_soa(switch_core_session_t *session, switch_bool_t partner)
+{
+	switch_core_session_t *other_session;
+	struct private_object *tech_pvt = switch_core_session_get_private(session);
+
+	sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
+
+	if (partner && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
+		if (switch_core_session_compare(session, other_session)) {
+			struct private_object *other_tech_pvt = switch_core_session_get_private(other_session);
+			
+			sofia_clear_flag(other_tech_pvt, TFLAG_ENABLE_SOA);
+		}
+		switch_core_session_rwunlock(other_session);
+	}
+
+}
+
 
 /* For Emacs:
  * Local Variables: