diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h
index 6e4c44af2f..e8cec64927 100644
--- a/src/include/switch_core_media.h
+++ b/src/include/switch_core_media.h
@@ -213,6 +213,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);
diff --git a/src/include/switch_types.h b/src/include/switch_types.h
index 78f4f0d557..6fe594f9f7 100644
--- a/src/include/switch_types.h
+++ b/src/include/switch_types.h
@@ -1537,7 +1537,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;
 
 
diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.c b/src/mod/applications/mod_spandsp/mod_spandsp.c
index fdbb44c5a6..4e4319bfb8 100644
--- a/src/mod/applications/mod_spandsp/mod_spandsp.c
+++ b/src/mod/applications/mod_spandsp/mod_spandsp.c
@@ -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";
 	}
diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
index 3d175a18e5..81dabb3f44 100644
--- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
+++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
@@ -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);
 	}
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index ba6ef2a929..73b2a384b1 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -6585,7 +6585,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)) {
@@ -6614,13 +6614,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);
@@ -7939,8 +7934,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;
 					}
 				}
diff --git a/src/switch_core_media.c b/src/switch_core_media.c
index 635a00f5b7..81bfb2b6cf 100644
--- a/src/switch_core_media.c
+++ b/src/switch_core_media.c
@@ -3726,6 +3726,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)
 {
@@ -3929,22 +3940,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)) {
 					match = 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);
+					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);
 					match = 0;
-					goto done;
+					
+					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;
 					}
@@ -3982,10 +4001,13 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
 
 							pass = 0;
 							match = 0;
+							match = 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");
@@ -4036,7 +4058,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 =/) */
-				match = 1;
+				if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE)) {
+					match = 1;
+				} else {
+
+					match = 0;
+				}
+
+				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 %s POSSIBLE on %s\n",
+								  switch_channel_get_name(channel),
+								  match ? "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) {
@@ -5035,6 +5069,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
 
  done:
 
+ t38_done:
+	
 	if (parser) {
 		sdp_parser_free(parser);
 	}
@@ -5045,6 +5081,30 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
 	return match;
 }
 
+//?
+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)