]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-9855: [mod_spandsp] Refused T38 reinvite on b-leg breaks T38 negotiation on a...
authorBrian West <brian@freeswitch.org>
Thu, 5 Jan 2017 21:51:52 +0000 (15:51 -0600)
committerBrian West <brian@freeswitch.org>
Thu, 5 Jan 2017 21:51:52 +0000 (15:51 -0600)
src/include/switch_core_media.h
src/include/switch_types.h
src/mod/applications/mod_spandsp/mod_spandsp.c
src/mod/applications/mod_spandsp/mod_spandsp_fax.c
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_presence.c
src/switch_core.c
src/switch_core_media.c

index fff45129d468e5e7407e923d6322990e46793cbd..d794918cb371ac0832e64673c34f63a2759a6fa7 100644 (file)
@@ -216,6 +216,7 @@ SWITCH_DECLARE(void) switch_core_media_pass_zrtp_hash(switch_core_session_t *ses
 SWITCH_DECLARE(const char *) switch_core_media_get_zrtp_hash(switch_core_session_t *session, switch_media_type_t type, switch_bool_t local);
 SWITCH_DECLARE(void) switch_core_media_pass_zrtp_hash2(switch_core_session_t *aleg_session, switch_core_session_t *bleg_session);
 SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session, int sendonly);
+SWITCH_DECLARE(void) switch_core_media_reset_t38(switch_core_session_t *session);
 SWITCH_DECLARE(void) switch_core_media_copy_t38_options(switch_t38_options_t *t38_options, switch_core_session_t *session);
 SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *session, const char *r_sdp, uint8_t *proceed, switch_sdp_type_t sdp_type);
 SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_session_t *session, int force);
index 3d924cbfc676110ffc6a5511412d392b6e382e65..b2f91735a5508eb7ec2c1f902f8795359e85bcc9 100644 (file)
@@ -1562,7 +1562,8 @@ typedef enum {
        CF_APP_T38 = (1 << 1),
        CF_APP_T38_REQ = (1 << 2),
        CF_APP_T38_FAIL = (1 << 3),
-       CF_APP_T38_NEGOTIATED = (1 << 4)
+       CF_APP_T38_NEGOTIATED = (1 << 4),
+       CF_APP_T38_POSSIBLE = (1 << 5)
 } switch_channel_app_flag_t;
 
 
index fdbb44c5a6dc4c245823784606c0b5dfdd71e488..4e4319bfb804e8c5ce3691536fb8478d3b5f9998 100644 (file)
@@ -221,6 +221,8 @@ SWITCH_STANDARD_APP(t38_gateway_function)
                }
        }
 
+       switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE);
+               
        if (zstr(direction) || strcasecmp(direction, "self")) {
                direction = "peer";
        }
index 3d175a18e5d9a7d4cdcb1e0b3a81a4a60591ac77..81dabb3f4483cca09fabb0487f7d4063cc0b3a8c 100644 (file)
@@ -1354,7 +1354,12 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat
 
        counter_increment();
 
-
+       if (app_mode == FUNCTION_GW ||
+               switch_channel_var_true(channel, "fax_enable_t38") ||
+               switch_channel_var_true(channel, "fax_enable_t38_insist")) {
+               switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE);
+       }
+       
        pvt = pvt_init(session, app_mode);
        switch_channel_set_private(channel, "_fax_pvt", pvt);
 
@@ -1599,6 +1604,8 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat
        /* Destroy the SpanDSP structures */
        spanfax_destroy(pvt);
 
+       switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE);
+       
        /* restore the original codecs over the channel */
 
        switch_core_session_set_read_codec(session, NULL);
@@ -2071,6 +2078,9 @@ switch_bool_t t38_gateway_start(switch_core_session_t *session, const char *app,
                switch_channel_set_app_flag_key("T38", peer ? channel : other_channel, CF_APP_TAGGED);
                switch_channel_clear_app_flag_key("T38", peer ? other_channel : channel, CF_APP_TAGGED);
 
+               switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE);
+               switch_channel_set_app_flag_key("T38", other_channel, CF_APP_T38_POSSIBLE);
+               
                switch_channel_set_flag(channel, CF_REDIRECT);
                switch_channel_set_state(channel, CS_RESET);
 
@@ -2268,6 +2278,7 @@ switch_status_t spandsp_fax_detect_session(switch_core_session_t *session,
        switch_codec_implementation_t read_impl = { 0 };
        switch_core_session_get_read_impl(session, &read_impl);
 
+       
        if (timeout) {
                to = switch_epoch_time_now(NULL) + timeout;
        }
@@ -2281,6 +2292,8 @@ switch_status_t spandsp_fax_detect_session(switch_core_session_t *session,
                return SWITCH_STATUS_MEMERR;
        }
 
+       switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE);
+       
        if (app) {
                cont->app = switch_core_session_strdup(session, app);
        }
index 369277e2d9a545eacd56980279e22e9152120ba1..de780ef41ac8f7c8361ae9c2e8828110433ec003 100644 (file)
@@ -6770,7 +6770,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
                                        const char *r_sdp = NULL;
                                        switch_core_session_message_t *msg;
                                        private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
-                                       switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
+                                       //switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
 
                                        if (sip->sip_payload && sip->sip_payload->pl_data &&
                                                sip->sip_content_type && sip->sip_content_type->c_subtype && switch_stristr("sdp", sip->sip_content_type->c_subtype)) {
@@ -6799,13 +6799,8 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
                                                switch_core_session_rwunlock(other_session);
                                                goto end;
                                        } else if (status > 299) {
-                                               switch_channel_set_private(channel, "t38_options", NULL);
-                                               switch_channel_set_private(other_channel, "t38_options", NULL);
-                                               switch_channel_clear_flag(channel, CF_T38_PASSTHRU);
-                                               switch_channel_clear_flag(other_channel, CF_T38_PASSTHRU);
-                                               switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38);
-                                               switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38_REQ);
-                                               switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_FAIL);
+                                               switch_core_media_reset_t38(session);
+                                               switch_core_media_reset_t38(other_session);
                                        } else if (status == 200 && switch_channel_test_flag(channel, CF_T38_PASSTHRU) && 
                                                           has_t38 && sip->sip_payload && sip->sip_payload->pl_data) {
                                                switch_t38_options_t *t38_options = switch_core_media_extract_t38_options(session, sip->sip_payload->pl_data);
@@ -8127,8 +8122,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                        goto done;
                                                }
 
-                                               switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
-                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite Codec Error!\n");
+                                               switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
+                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Reinvite resulted in codec negotiation failure.\n");
                                                is_ok = 0;
                                        }
                                }
index 6100766b41d676a72e84a1c075d6e1d084372c07..827a305cc91dc39065e77d6cc8c11321e88067f5 100644 (file)
@@ -3465,6 +3465,8 @@ static int broadsoft_sla_gather_state_callback(void *pArg, int argc, char **argv
                        callee_name = "unknown";
                }
 
+               //callee_number = "666";
+               
                if (data) {
                        tmp = switch_core_sprintf(sh->pool,
                                                                          "%s,<sip:%s>;%s;appearance-state=%s;appearance-uri=\"\\\"%s\\\" <sip:%s@%s>\"",
index 606ccb59be794a103e48bcdf5257c2e77946b041..d38f3d1a92d8bb9689f103d5ae73158452cee7f5 100644 (file)
@@ -2795,6 +2795,7 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *
                        switch_set_flag((&runtime), SCF_RESTART);
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
                } else {
+                       assert(0);
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n");
 #ifdef _MSC_VER
                        fclose(stdin);
index da406d3ab7bd6848e1c1e50085d5d6832b27f919..8caa3a88d9f7a4d959922111664fc82f6f13ec31 100644 (file)
@@ -2450,7 +2450,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
        engine = &smh->engines[type];
 
        if (type == SWITCH_MEDIA_TYPE_AUDIO && ! switch_channel_test_flag(session->channel, CF_AUDIO)) {
-               //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reading audio from a non-audio session.\n");
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s Reading audio from a non-audio session.\n", switch_channel_get_name(session->channel));
                switch_yield(50000);
                return SWITCH_STATUS_INUSE;
        }
@@ -4078,6 +4078,17 @@ static void clear_pmaps(switch_rtp_engine_t *engine)
        }
 }
 
+static void restore_pmaps(switch_rtp_engine_t *engine)
+{
+       payload_map_t *pmap;
+       int top = 0;
+       
+       for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) {
+               pmap->negotiated = 1;
+               if (!top++) pmap->current = 1;
+       }
+}
+
 //?
 SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *session, const char *r_sdp, uint8_t *proceed, switch_sdp_type_t sdp_type)
 {
@@ -4387,22 +4398,30 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                        switch_channel_set_flag(session->channel, CF_IMAGE_SDP);
 
                        if (m->m_port) {
-                               switch_t38_options_t *t38_options = switch_core_media_process_udptl(session, sdp, m);
-
                                if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38_NEGOTIATED)) {
                                        fmatch = 1;
                                        goto done;
                                }
 
-                               if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) {
+                               if (switch_channel_var_true(channel, "refuse_t38")) {
                                        switch_channel_clear_app_flag_key("T38", session->channel, CF_APP_T38);
-                                       match = 0;
-                                       goto done;
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 REFUSE on %s\n",
+                                                                         switch_channel_get_name(channel),
+                                                                         sdp_type == SDP_TYPE_RESPONSE ? "response" : "request");
+
+                                       restore_pmaps(a_engine);
+                                       fmatch = 0;
+                                       
+                                       goto t38_done;
                                } else {
+                                       switch_t38_options_t *t38_options = switch_core_media_process_udptl(session, sdp, m);
                                        const char *var = switch_channel_get_variable(channel, "t38_passthru");
                                        int pass = switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU);
-
-
+                                       
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 ACCEPT on %s\n",
+                                                                         switch_channel_get_name(channel),
+                                                                         sdp_type == SDP_TYPE_RESPONSE ? "response" : "request");
+                                       
                                        if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38)) {
                                                if (proceed) *proceed = 0;
                                        }
@@ -4440,10 +4459,13 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
 
                                                        pass = 0;
                                                        match = 0;
+                                                       fmatch = 0;
                                                        goto done;
                                                }
 
-
+                                               switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE);
+                                               switch_channel_set_app_flag_key("T38", other_channel, CF_APP_T38_POSSIBLE);
+                                               
                                                if (switch_true(switch_channel_get_variable(session->channel, "t38_broken_boolean")) && 
                                                        switch_true(switch_channel_get_variable(session->channel, "t38_pass_broken_boolean"))) {
                                                        switch_channel_set_variable(other_channel, "t38_broken_boolean", "true");
@@ -4494,7 +4516,19 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
 
 
                                /* do nothing here, mod_fax will trigger a response (if it's listening =/) */
-                               fmatch = 1;
+                               if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE)) {
+                                       fmatch = 1;
+                               } else {
+
+                                       fmatch = 0;
+                               }
+
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 %s POSSIBLE on %s\n",
+                                                                 switch_channel_get_name(channel),
+                                                                 fmatch ? "IS" : "IS NOT",
+                                                                 sdp_type == SDP_TYPE_RESPONSE ? "response" : "request");
+
+                               
                                goto done;
                        }
                } else if (m->m_type == sdp_media_audio && m->m_port && got_audio && got_savp) {
@@ -5615,6 +5649,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                switch_channel_clear_flag(channel, CF_IMAGE_SDP);
        }
 
+ t38_done:
+       
        if (parser) {
                sdp_parser_free(parser);
        }
@@ -5625,6 +5661,30 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
        return match || vmatch || tmatch || fmatch;
 }
 
+//?
+SWITCH_DECLARE(void) switch_core_media_reset_t38(switch_core_session_t *session)
+{
+       switch_rtp_engine_t *a_engine;
+       switch_media_handle_t *smh;
+       switch_channel_t *channel = switch_core_session_get_channel(session);
+       
+       switch_assert(session);
+
+       if (!(smh = session->media_handle)) {
+               return;
+       }
+
+       a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
+
+       restore_pmaps(a_engine);
+
+       switch_channel_set_private(channel, "t38_options", NULL);
+       switch_channel_clear_flag(channel, CF_T38_PASSTHRU);
+       switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38);
+       switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38_REQ);
+       switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_FAIL);
+}
+
 //?
 
 SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session, int sendonly)