--- include/asterisk/rtp.h.orig	2008-03-18 13:35:42.000000000 +0200
+++ include/asterisk/rtp.h	2008-03-18 13:35:58.000000000 +0200
@@ -251,6 +251,9 @@
 
 int ast_rtp_codec_getformat(int pt);
 
+void ast_rtp_set_chan_name(struct ast_rtp *, const char *);
+void ast_rtp_set_chan_id(struct ast_rtp *, const char *);
+
 /*! \brief Set rtp timeout */
 void ast_rtp_set_rtptimeout(struct ast_rtp *rtp, int timeout);
 /*! \brief Set rtp hold timeout */
--- main/rtp.c.orig	2008-04-08 14:53:18.000000000 +0300
+++ main/rtp.c	2008-04-08 14:54:14.000000000 +0300
@@ -81,6 +81,7 @@
 static int rtpstart;			/*!< First port for RTP sessions (set in rtp.conf) */
 static int rtpend;			/*!< Last port for RTP sessions (set in rtp.conf) */
 static int rtpdebug;			/*!< Are we debugging? */
+static int rtpdebugdtmf;		/*!< Are we debugging DTMFs? */
 static int rtcpdebug;			/*!< Are we debugging RTCP? */
 static int rtcpstats;			/*!< Are we debugging RTCP? */
 static int rtcpinterval = RTCP_DEFAULT_INTERVALMS; /*!< Time between rtcp reports in millisecs */
@@ -168,6 +169,8 @@
 	struct ast_codec_pref pref;
 	struct ast_rtp *bridged;        /*!< Who we are Packet bridged to */
 	int set_marker_bit:1;           /*!< Whether to set the marker bit or not */
+	char chan_name[100];
+	char chan_id[100];
 };
 
 /* Forward declarations */
@@ -669,8 +672,8 @@
 	struct ast_frame *f = NULL;
 	event = ntohl(*((unsigned int *)(data)));
 	event &= 0x001F;
-	if (option_debug > 2 || rtpdebug)
-		ast_log(LOG_DEBUG, "Cisco DTMF Digit: %08x (len = %d)\n", event, len);
+	if (option_debug > 2 || rtpdebug || rtpdebugdtmf)
+		ast_log(LOG_DEBUG, "Channel: %s %s Cisco DTMF packet: %08x (len = %d)\n", rtp->chan_name, rtp->chan_id, event, len);
 	if (event < 10) {
 		resp = '0' + event;
 	} else if (event < 11) {
@@ -684,12 +687,24 @@
 	}
 	if (rtp->resp && (rtp->resp != resp)) {
 		f = send_dtmf(rtp, AST_FRAME_DTMF_END);
+		ast_log(LOG_DEBUG, "Channel: %s %s Cisco DTMF event: %c\n", rtp->chan_name, rtp->chan_id, rtp->resp);
 	}
 	rtp->resp = resp;
 	rtp->dtmfcount = dtmftimeout;
 	return f;
 }
 
+void ast_rtp_set_chan_id(struct ast_rtp *rtp, const char *chan_id) {
+	if (rtp == NULL || chan_id == NULL)
+		return;
+	snprintf(rtp->chan_id, sizeof(rtp->chan_id), "%s", chan_id);
+}
+
+void ast_rtp_set_chan_name(struct ast_rtp *rtp, const char *chan_name) {
+	if (rtp == NULL || chan_name == NULL)
+		return;
+	snprintf(rtp->chan_name, sizeof(rtp->chan_name), "%s", chan_name);
+}
 /*! 
  * \brief Process RTP DTMF and events according to RFC 2833.
  * 
@@ -1051,6 +1066,10 @@
 	struct rtpPayloadType rtpPT;
 	int reconstruct = ntohl(rtpheader[0]);
 
+	/* If we are listening for DTMF - then feed all packets into the core  to keep the RTP stream consistent when relaying DTMFs */
+	if (ast_test_flag(rtp, FLAG_P2P_NEED_DTMF))
+		return -1;
+
 	/* Get fields from packet */
 	payload = (reconstruct & 0x7f0000) >> 16;
 	mark = (((reconstruct & 0x800000) >> 23) != 0);
@@ -1062,10 +1081,6 @@
 	if (!bridged->current_RTP_PT[payload].code)
 		return -1;
 
-	/* If the payload is DTMF, and we are listening for DTMF - then feed it into the core */
-	if (ast_test_flag(rtp, FLAG_P2P_NEED_DTMF) && !rtpPT.isAstFormat && rtpPT.code == AST_RTP_DTMF)
-		return -1;
-
 	/* Otherwise adjust bridged payload to match */
 	bridged_payload = ast_rtp_lookup_code(bridged, rtpPT.isAstFormat, rtpPT.code);
 
@@ -1254,11 +1269,12 @@
 		/* This is special in-band data that's not one of our codecs */
 		if (rtpPT.code == AST_RTP_DTMF) {
 			/* It's special -- rfc2833 process it */
-			if (rtp_debug_test_addr(&sin)) {
+			if (rtp_debug_test_addr(&sin) || rtpdebugdtmf) {
 				unsigned char *data;
 				unsigned int event;
 				unsigned int event_end;
 				unsigned int duration;
+
 				data = rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen;
 				event = ntohl(*((unsigned int *)(data)));
 				event >>= 24;
@@ -1267,9 +1283,12 @@
 				event_end >>= 24;
 				duration = ntohl(*((unsigned int *)(data)));
 				duration &= 0xFFFF;
-				ast_verbose("Got  RTP RFC2833 from   %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u, mark %d, event %08x, end %d, duration %-5.5d) \n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp, res - hdrlen, (mark?1:0), event, ((event_end & 0x80)?1:0), duration);
+
+				ast_verbose("Channel: %s %s Got RTP RFC2833 from %s:%u to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u, mark %d, event %08x, end %d, duration %-5.5d)\n", rtp->chan_name, rtp->chan_id, ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), ast_inet_ntoa(rtp->us.sin_addr), ntohs(rtp->us.sin_port), payloadtype, seqno, timestamp, res - hdrlen, (mark?1:0), event, ((event_end & 0x80)?1:0), duration);
 			}
 			f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno, timestamp);
+			if (rtpdebugdtmf && f)
+				ast_verbose("Channel: %s %s Got RFC2833 DTMF event %c of type %s\n", rtp->chan_name, rtp->chan_id, f->subclass, (f->frametype == AST_FRAME_DTMF_BEGIN ? "DTMF BEGIN" : (f->frametype == AST_FRAME_DTMF_END ? "DTMF_END" : "UNKNOWN")));
 		} else if (rtpPT.code == AST_RTP_CISCO_DTMF) {
 			/* It's really special -- process it the Cisco way */
 			if (rtp->lastevent <= seqno || (rtp->lastevent >= 65530 && seqno <= 6)) {
@@ -2198,8 +2217,9 @@
 			ast_log(LOG_ERROR, "RTP Transmission error to %s:%u: %s\n",
 				ast_inet_ntoa(rtp->them.sin_addr),
 				ntohs(rtp->them.sin_port), strerror(errno));
-		if (rtp_debug_test_addr(&rtp->them))
-			ast_verbose("Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
+		if (rtp_debug_test_addr(&rtp->them) || rtpdebugdtmf)
+			ast_verbose("Channel: %s %s Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
+				    rtp->chan_name, rtp->chan_id,
 				    ast_inet_ntoa(rtp->them.sin_addr),
 				    ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
 		/* Increment sequence number */
@@ -2242,8 +2262,9 @@
 		ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n",
 			ast_inet_ntoa(rtp->them.sin_addr),
 			ntohs(rtp->them.sin_port), strerror(errno));
-	if (rtp_debug_test_addr(&rtp->them))
-		ast_verbose("Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
+	if (rtp_debug_test_addr(&rtp->them) || rtpdebugdtmf)
+		ast_verbose("Channel: %s %s Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
+			    rtp->chan_name, rtp->chan_id,
 			    ast_inet_ntoa(rtp->them.sin_addr),
 			    ntohs(rtp->them.sin_port), rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
 
@@ -3481,6 +3502,16 @@
 	return RESULT_SUCCESS;
 }
 
+static int rtp_do_debug_dtmf(int fd, int argc, char *argv[])
+{
+	if (argc != 3)
+		return RESULT_SHOWUSAGE;
+
+	rtpdebugdtmf = 1;
+	ast_cli(fd, "RTP DTMF debugging enabled\n");
+	return RESULT_SUCCESS;
+}
+
 static int rtp_do_debug(int fd, int argc, char *argv[])
 {
 	if (argc != 2) {
@@ -3541,6 +3572,7 @@
 	if (argc != 3)
 		return RESULT_SHOWUSAGE;
 	rtpdebug = 0;
+	rtpdebugdtmf = 0;
 	ast_cli(fd,"RTP Debugging Disabled\n");
 	return RESULT_SUCCESS;
 }
@@ -3601,7 +3633,7 @@
 }
 
 static char debug_usage[] =
-  "Usage: rtp debug [ip host[:port]]\n"
+  "Usage: rtp debug [ip host[:port] | dtmf]\n"
   "       Enable dumping of all RTP packets to and from host.\n";
 
 static char no_debug_usage[] =
@@ -3676,6 +3708,10 @@
 	rtp_do_debug, "Enable RTP debugging",
 	debug_usage },
 
+	{ { "rtp", "debug", "dtmf", NULL },
+	rtp_do_debug_dtmf, "Enable RTP debugging on DTMFs",
+	debug_usage },
+
 	{ { "rtp", "debug", "off", NULL },
 	rtp_no_debug, "Disable RTP debugging",
 	no_debug_usage, NULL, &cli_rtp_no_debug_deprecated },
--- channels/chan_sip.c.orig	2008-06-10 00:29:41.000000000 -0700
+++ channels/chan_sip.c	2008-06-10 00:42:00.000000000 -0700
@@ -3813,6 +3813,7 @@
 		ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
 	else {
 		p->owner = newchan;
+		ast_rtp_set_chan_name(p->rtp, newchan->name);
 		/* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native
 		   RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be
 		   able to do this if the masquerade happens before the bridge breaks (e.g., AMI
@@ -4085,6 +4086,7 @@
 	if (i->rtp) {
 		tmp->fds[0] = ast_rtp_fd(i->rtp);
 		tmp->fds[1] = ast_rtcp_fd(i->rtp);
+		ast_rtp_set_chan_id(i->rtp, i->callid);
 	}
 	if (needvideo && i->vrtp) {
 		tmp->fds[2] = ast_rtp_fd(i->vrtp);
@@ -4112,6 +4114,8 @@
 	if (!ast_strlen_zero(i->language))
 		ast_string_field_set(tmp, language, i->language);
 	i->owner = tmp;
+	ast_rtp_set_chan_name(i->rtp, tmp->name);
+
 	ast_module_ref(ast_module_info->self);
 	ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
 	/*Since it is valid to have extensions in the dialplan that have unescaped characters in them
@@ -4531,8 +4535,10 @@
 	build_via(p);
 	if (!callid)
 		build_callid_pvt(p);
-	else
+	else {
 		ast_string_field_set(p, callid, callid);
+		ast_rtp_set_chan_id(p->rtp, p->callid);
+	}
 	/* Assign default music on hold class */
 	ast_string_field_set(p, mohinterpret, default_mohinterpret);
 	ast_string_field_set(p, mohsuggest, default_mohsuggest);