diff --git a/apps/app_fax.c b/apps/app_fax.c
index b6a4b02f6635a4d9a6f83639c9dec935b73afe7c..39e00641a7d4502d4cddce43b46990dfae3d3496 100644
--- a/apps/app_fax.c
+++ b/apps/app_fax.c
@@ -598,6 +598,7 @@ static int transmit_t38(fax_session *s)
 	struct timeval now, start, state_change, last_frame;
 	t30_state_t *t30state;
 	t38_core_state_t *t38state;
+	struct ast_control_t38_parameters t38_parameters = { .request_response = AST_T38_REQUEST_TERMINATE, };
 
 #if SPANDSP_RELEASE_DATE >= 20080725
 	/* for spandsp shaphots 0.0.6 and higher */
@@ -613,7 +614,8 @@ static int transmit_t38(fax_session *s)
 	memset(&t38, 0, sizeof(t38));
 	if (t38_terminal_init(&t38, s->caller_mode, t38_tx_packet_handler, s->chan) == NULL) {
 		ast_log(LOG_WARNING, "Unable to start T.38 termination.\n");
-		return -1;
+		res = -1;
+		goto disable_t38;
 	}
 
 	t38_set_max_datagram_size(t38state, s->t38parameters.max_ifp);
@@ -703,6 +705,57 @@ static int transmit_t38(fax_session *s)
 	t30_terminate(t30state);
 	t38_terminal_release(&t38);
 
+disable_t38:
+	if (ast_channel_get_t38_state(s->chan) == T38_STATE_NEGOTIATED) {
+		if (ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) == 0) {
+			/* wait up to five seconds for negotiation to complete */
+			unsigned int timeout = 5000;
+			int ms;
+			
+			ast_debug(1, "Shutting down T.38 on %s\n", s->chan->name);
+			while (timeout > 0) {
+				ms = ast_waitfor(s->chan, 1000);
+				if (ms < 0) {
+					ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", s->chan->name);
+					return -1;
+				}
+				if (!ms) {
+					/* nothing happened */
+					if (timeout > 0) {
+						timeout -= 1000;
+						continue;
+					} else {
+						ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 shutdown.\n", s->chan->name);
+						break;
+					}
+				}
+				if (!(inf = ast_read(s->chan))) {
+					return -1;
+				}
+				if ((inf->frametype == AST_FRAME_CONTROL) &&
+				    (inf->subclass == AST_CONTROL_T38_PARAMETERS) &&
+				    (inf->datalen == sizeof(t38_parameters))) {
+					struct ast_control_t38_parameters *parameters = inf->data.ptr;
+					
+					switch (parameters->request_response) {
+					case AST_T38_NEGOTIATED:
+						ast_debug(1, "Shut down T.38 on %s\n", s->chan->name);
+						break;
+					case AST_T38_REFUSED:
+						ast_log(LOG_WARNING, "channel '%s' refused to disable T.38\n", s->chan->name);
+						break;
+					default:
+						ast_log(LOG_ERROR, "channel '%s' failed to disable T.38\n", s->chan->name);
+						break;
+					}
+					ast_frfree(inf);
+					break;
+				}
+				ast_frfree(inf);
+			}
+		}
+	}
+
 	return res;
 }
 
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 4281808ad44666d722f4591c079ba46d23096a92..7c619d414fdec9e7af70a25ee493d480727a22bf 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -6323,8 +6323,7 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
 						ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
 					}
 				} else if (p->t38.state == T38_ENABLED) {
-					change_t38_state(p, T38_DISABLED);
-					transmit_reinvite_with_sdp(p, FALSE, FALSE);
+					/* drop frame, can't sent VOICE frames while in T.38 mode */
 				} else {
 					p->lastrtptx = time(NULL);
 					res = ast_rtp_instance_write(p->rtp, frame);