]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
SFSIP-180 report hack in sofia lib to pekka for better answer
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 21 Oct 2009 23:01:37 +0000 (23:01 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 21 Oct 2009 23:01:37 +0000 (23:01 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15190 d0543943-73ff-0310-b7d9-9358b9ac24b2

libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c

index 4459a9ede5168ca55748fd89f2c3932048e3c55f..2630dc29133d6275b8423a39640897509273cd1a 100644 (file)
@@ -943,14 +943,19 @@ static int nua_session_client_response(nua_client_request_t *cr,
   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 */
index c4a5d82d6b47933825486bbd1cfca94db566f4bd..eb7975e0809d6af8bd662025dd4a6fdcf2df8516 100644 (file)
@@ -3474,6 +3474,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
        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 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                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 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                        }
                                        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 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                        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 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                }
                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;
index abcc5a6e7da5b812fb08b6e249826ceb7a132fa8..d6100e28abb353662de96d46839d72adee34bd51 100644 (file)
@@ -2321,7 +2321,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
                //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 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, sdp_session_t *
 
                } 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 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, sdp_session_t *
                  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 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, sdp_session_t *
                                        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;