diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index 6c6aa1578af8833e43f7cf78c4e2945ec75ccb8d..d18729ddfbe52c03846916c4cc22c79d467ddec5 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -191,12 +191,13 @@ struct ast_rtp {
 	int rtpkeepalive;		/*!< Send RTP comfort noice packets for keepalive */
 
 	/* DTMF Reception Variables */
-	char resp;
-	unsigned int lastevent;
-	unsigned int dtmf_duration;     /*!< Total duration in samples since the digit start event */
-	unsigned int dtmf_timeout;      /*!< When this timestamp is reached we consider END frame lost and forcibly abort digit */
+	char resp;                        /*!< The current digit being processed */
+	unsigned int last_seqno;          /*!< The last known sequence number for any DTMF packet */
+	unsigned int last_end_timestamp;  /*!< The last known timestamp received from an END packet */
+	unsigned int dtmf_duration;       /*!< Total duration in samples since the digit start event */
+	unsigned int dtmf_timeout;        /*!< When this timestamp is reached we consider END frame lost and forcibly abort digit */
 	unsigned int dtmfsamples;
-	enum ast_rtp_dtmf_mode dtmfmode;/*!< The current DTMF mode of the RTP stream */
+	enum ast_rtp_dtmf_mode dtmfmode;  /*!< The current DTMF mode of the RTP stream */
 	/* DTMF Transmission Variables */
 	unsigned int lastdigitts;
 	char sending_digit;	/*!< boolean - are we sending digits */
@@ -2155,8 +2156,10 @@ static struct ast_frame *create_dtmf_frame(struct ast_rtp_instance *instance, en
 		rtp->dtmfsamples = 0;
 		return &ast_null_frame;
 	}
-	ast_debug(1, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp,
-		  ast_sockaddr_stringify(&remote_address));
+	ast_debug(1, "Creating %s DTMF Frame: %d (%c), at %s\n",
+		type == AST_FRAME_DTMF_END ? "END" : "BEGIN",
+		rtp->resp, rtp->resp,
+		ast_sockaddr_stringify(&remote_address));
 	if (rtp->resp == 'X') {
 		rtp->f.frametype = AST_FRAME_CONTROL;
 		rtp->f.subclass.integer = AST_CONTROL_FLASH;
@@ -2220,12 +2223,12 @@ static void process_dtmf_rfc2833(struct ast_rtp_instance *instance, unsigned cha
 	}
 
 	if (ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_DTMF_COMPENSATE)) {
-		if ((rtp->lastevent != timestamp) || (rtp->resp && rtp->resp != resp)) {
+		if ((rtp->last_end_timestamp != timestamp) || (rtp->resp && rtp->resp != resp)) {
 			rtp->resp = resp;
 			rtp->dtmf_timeout = 0;
 			f = ast_frdup(create_dtmf_frame(instance, AST_FRAME_DTMF_END, ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_DTMF_COMPENSATE)));
 			f->len = 0;
-			rtp->lastevent = timestamp;
+			rtp->last_end_timestamp = timestamp;
 			AST_LIST_INSERT_TAIL(frames, f, frame_list);
 		}
 	} else {
@@ -2242,31 +2245,41 @@ static void process_dtmf_rfc2833(struct ast_rtp_instance *instance, unsigned cha
 		}
 		new_duration = (new_duration & ~0xFFFF) | samples;
 
-		/* The second portion of this check is to not mistakenly
-		 * stop accepting DTMF if the seqno rolls over beyond
-		 * 65535.
-		 */
-		if (rtp->lastevent > seqno && rtp->lastevent - seqno < 50) {
-			/* Out of order frame. Processing this can cause us to
-			 * improperly duplicate incoming DTMF, so just drop
-			 * this.
-			 */
-			return;
-		}
-
 		if (event_end & 0x80) {
 			/* End event */
-			if ((rtp->lastevent != seqno) && rtp->resp) {
+			if ((rtp->last_seqno != seqno) && (timestamp > rtp->last_end_timestamp)) {
+				rtp->last_end_timestamp = timestamp;
 				rtp->dtmf_duration = new_duration;
+				rtp->resp = resp;
 				f = ast_frdup(create_dtmf_frame(instance, AST_FRAME_DTMF_END, 0));
 				f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(&f->subclass.format)), ast_tv(0, 0));
 				rtp->resp = 0;
 				rtp->dtmf_duration = rtp->dtmf_timeout = 0;
 				AST_LIST_INSERT_TAIL(frames, f, frame_list);
+			} else if (rtpdebug) {
+				ast_debug(1, "Dropping duplicate or out of order DTMF END frame (seqno: %d, ts %d, digit %c)\n",
+					seqno, timestamp, resp);
 			}
 		} else {
 			/* Begin/continuation */
 
+			/* The second portion of the seqno check is to not mistakenly
+			 * stop accepting DTMF if the seqno rolls over beyond
+			 * 65535.
+			 */
+			if ((rtp->last_seqno > seqno && rtp->last_seqno - seqno < 50)
+				|| timestamp <= rtp->last_end_timestamp) {
+				/* Out of order frame. Processing this can cause us to
+				 * improperly duplicate incoming DTMF, so just drop
+				 * this.
+				 */
+				if (rtpdebug) {
+					ast_debug(1, "Dropping out of order DTMF frame (seqno %d, ts %d, digit %c)\n",
+						seqno, timestamp, resp);
+				}
+				return;
+			}
+
 			if (rtp->resp && rtp->resp != resp) {
 				/* Another digit already began. End it */
 				f = ast_frdup(create_dtmf_frame(instance, AST_FRAME_DTMF_END, 0));
@@ -2290,7 +2303,7 @@ static void process_dtmf_rfc2833(struct ast_rtp_instance *instance, unsigned cha
 			rtp->dtmf_timeout = timestamp + rtp->dtmf_duration + dtmftimeout;
 		}
 
-		rtp->lastevent = seqno;
+		rtp->last_seqno = seqno;
 	}
 
 	rtp->dtmfsamples = samples;