Revision
15190
Author
anthm
Date
2009-10-21 18:01:37 -0500 (Wed, 21 Oct 2009)

Log Message

SFSIP-180 report hack in sofia lib to pekka for better answer

Modified Paths

Diff

Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c (15189 => 15190)


--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c	2009-10-21 20:57:46 UTC (rev 15189)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c	2009-10-21 23:01:37 UTC (rev 15190)
@@ -943,14 +943,19 @@
   SU_DEBUG_5(("nua(%p): %s: %s %s in %u %s\n", \
 	      (void *)nh, cr->cr_method_name, (m), received, status, phrase))
 
+ retry:
+
   if (!ss || !sip || 300 <= status)
     /* Xyzzy */;
   else if (!session_get_description(sip, &sdp, &len))
     /* No SDP */;
   else if (cr->cr_answer_recv) {
     /* Ignore spurious answers after completing O/A */
-    LOG3("ignoring duplicate");
-    sdp = NULL;
+	  //LOG3("ignoring duplicate");
+	  //sdp = NULL;
+	  // we need to make sure its *actually* a dup, so we can't assume for now.
+	  cr->cr_answer_recv = 0;
+	  goto retry;
   }
   else if (cr->cr_offer_sent) {
     /* case 1: answer to our offer */

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


--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	2009-10-21 20:57:46 UTC (rev 15189)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	2009-10-21 23:01:37 UTC (rev 15190)
@@ -3474,6 +3474,7 @@
 	switch_core_session_t *other_session = NULL;
 	switch_channel_t *other_channel = NULL;
 	char st[80] = "";
+	int is_dup_sdp = 0;
 
 	tl_gets(tags,
 			NUTAG_CALLSTATE_REF(ss_state),
@@ -3519,18 +3520,23 @@
 		if (r_sdp) {
 			sdp_parser_t *parser;
 			sdp_session_t *sdp;
+			
+			if (!switch_strlen_zero(tech_pvt->remote_sdp_str) && !strcmp(tech_pvt->remote_sdp_str, r_sdp)) {
+				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Duplicate SDP\n%s\n", r_sdp);
+				is_dup_sdp = 1;
+			} else {
+				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp);
+				tech_pvt->remote_sdp_str = switch_core_session_strdup(session, r_sdp);
+				switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp);
 
-			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp);
-			tech_pvt->remote_sdp_str = switch_core_session_strdup(session, r_sdp);
-			switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp);
-
-			if ( sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) && (parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
-				if ((sdp = sdp_session(parser))) {
-					sofia_glue_set_r_sdp_codec_string(channel, (tech_pvt->profile?tech_pvt->profile->codec_string:NULL), sdp);
+				if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) && (parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
+					if ((sdp = sdp_session(parser))) {
+						sofia_glue_set_r_sdp_codec_string(channel, (tech_pvt->profile?tech_pvt->profile->codec_string:NULL), sdp);
+					}
+					sdp_parser_free(parser);
 				}
-				sdp_parser_free(parser);
+				sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp);
 			}
-			sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp);
 		}
 	}
 
@@ -3848,6 +3854,8 @@
 					}
 					goto done;
 				} else {
+					sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE);
+
 					if (tech_pvt->num_codecs) {
 						if ((parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
 							if ((sdp = sdp_session(parser))) {
@@ -3861,14 +3869,15 @@
 							goto done;
 						}
 						sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
-						sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE);
+						
 						if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
 							switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite RTP Error!\n");
 							is_ok = 0;
 							switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
 						}
-						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing Reinvite\n");
+						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n");
 					} else {
+						sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE);
 						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite Codec Error!\n");
 						is_ok = 0;
 					}
@@ -3891,6 +3900,10 @@
 		}
 		break;
 	case nua_callstate_ready:
+		if (r_sdp && !is_dup_sdp && switch_rtp_ready(tech_pvt->rtp_session)) {
+			ss_state = nua_callstate_completed;
+			goto state_process;
+		}
 
 		if (r_sdp && sofia_test_flag(tech_pvt, TFLAG_NOSDP_REINVITE)) {
 			sdp_parser_t *parser;

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


--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c	2009-10-21 20:57:46 UTC (rev 15189)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c	2009-10-21 23:01:37 UTC (rev 15190)
@@ -2321,7 +2321,7 @@
 		//const char *port = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
 		char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session);
 		switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session);
-		
+
 		if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) && remote_port == tech_pvt->remote_sdp_audio_port) {
 			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n", switch_channel_get_name(tech_pvt->channel));
 			goto video;
@@ -2970,7 +2970,6 @@
 
 		} else if (m->m_type == sdp_media_audio && m->m_port && !got_audio) {
 			sdp_rtpmap_t *map;
-
 			for (attr = m->m_attributes; attr; attr = attr->a_next) {
 				if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
 					ptime = atoi(attr->a_value);
@@ -3065,26 +3064,43 @@
 		  greed:
 			x = 0;
 
-			if (tech_pvt->rm_encoding) {
+			if (tech_pvt->rm_encoding) {// && !sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
+				char *remote_host = tech_pvt->remote_sdp_audio_ip;
+				switch_port_t remote_port = tech_pvt->remote_sdp_audio_port;
+				int same = 0;
+
+				if (switch_rtp_ready(tech_pvt->rtp_session)) {
+					remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session);
+					remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session);
+				}
+				
 				for (map = m->m_rtpmaps; map; map = map->rm_next) {
-					if (map->rm_pt < 96) {
+					if (switch_strlen_zero(map->rm_encoding) && map->rm_pt < 96) {
 						match = (map->rm_pt == tech_pvt->pt) ? 1 : 0;
 					} else {
 						match = strcasecmp(switch_str_nil(map->rm_encoding), tech_pvt->iananame) ? 0 : 1;
 					}
 
-					if (match && connection->c_address && tech_pvt->remote_sdp_audio_ip && 
-						!strcmp(connection->c_address, tech_pvt->remote_sdp_audio_ip) && m->m_port == tech_pvt->remote_sdp_audio_port) {
-						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Our existing sdp is still good [%s %s:%d], let's keep it.\n",
-										  tech_pvt->rm_encoding, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port);
-						got_audio = 1;
+					if (match && connection->c_address && remote_host &&
+						!strcmp(connection->c_address, remote_host) && m->m_port == remote_port) {
+						same = 1;
+					} else {
+						same = 0;
 						break;
 					}
 				}
+
+				if (same) {
+					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 
+									  "Our existing sdp is still good [%s %s:%d], let's keep it.\n",
+									  tech_pvt->rm_encoding, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port);
+					got_audio = 1;
+				} else {
+					match = 0;
+					got_audio = 0;
+				}
 			}
-
-
-
+			
 			for (map = m->m_rtpmaps; map; map = map->rm_next) {
 				int32_t i;
 				uint32_t near_rate = 0;
@@ -3144,7 +3160,7 @@
 					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Compare [%s:%d:%u:%d]/[%s:%d:%u:%d]\n",
 									  rm_encoding, map->rm_pt, (int) map->rm_rate, ptime,
 									  imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000);
-					if (map->rm_pt < 96) {
+					if (switch_strlen_zero(map->rm_encoding) && map->rm_pt < 96) {
 						match = (map->rm_pt == imp->ianacode) ? 1 : 0;
 					} else {
 						match = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1;