Index: channels/chan_sip.c
===================================================================
--- channels/chan_sip.c	(revision 86631)
+++ channels/chan_sip.c	(working copy)
@@ -798,6 +798,7 @@
 #define SIP_DTMF_INBAND		(1 << 16)	/*!< DP: DTMF Support: Inband audio, only for ULAW/ALAW - "inband" */
 #define SIP_DTMF_INFO		(2 << 16)	/*!< DP: DTMF Support: SIP Info messages - "info" */
 #define SIP_DTMF_AUTO		(3 << 16)	/*!< DP: DTMF Support: AUTO switch between rfc2833 and in-band DTMF */
+#define SIP_DTMF_SHORTINFO      (4 << 16)       /*!< DP: DTMF Support: SIP Info messages - "info" - short variant */
 
 /* NAT settings - see nat2str() */
 #define SIP_NAT			(3 << 18)	/*!< DP: four settings, uses two bits */
@@ -1500,6 +1501,7 @@
 static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init);
 static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version);
 static int transmit_info_with_digit(struct sip_pvt *p, const char digit, unsigned int duration);
+static int transmit_shortinfo_with_digit(struct sip_pvt *p, const char digit, unsigned int duration);
 static int transmit_info_with_vidupdate(struct sip_pvt *p);
 static int transmit_message_with_text(struct sip_pvt *p, const char *text);
 static int transmit_refer(struct sip_pvt *p, const char *dest);
@@ -1744,6 +1746,7 @@
 static int add_line(struct sip_request *req, const char *line);
 static int add_text(struct sip_request *req, const char *text);
 static int add_digit(struct sip_request *req, char digit, unsigned int duration);
+static int add_digit_short(struct sip_request *req, char digit, unsigned int duration);
 static int add_vidupdate(struct sip_request *req);
 static void add_route(struct sip_request *req, struct sip_route *route);
 static int copy_header(struct sip_request *req, const struct sip_request *orig, const char *field);
@@ -4378,6 +4381,9 @@
 	case SIP_DTMF_INFO:
 		transmit_info_with_digit(p, digit, duration);
 		break;
+	case SIP_DTMF_SHORTINFO:
+		transmit_shortinfo_with_digit(p, digit, duration);
+		break;
 	case SIP_DTMF_RFC2833:
 		if (p->rtp)
 			ast_rtp_senddigit_end(p->rtp, digit);
@@ -4541,7 +4547,7 @@
 	}
 	sip_pvt_lock(i);
 
-	tmp->tech = ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO ?  &sip_tech_info : &sip_tech;
+	tmp->tech = ( ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO || ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO) ?  &sip_tech_info : &sip_tech;
 
 	/* Select our native format based on codec preference until we receive
 	   something from another device to the contrary. */
@@ -6761,6 +6767,26 @@
 	return 0;
 }
 
+/*! \brief Add DTMF INFO tone to sip message, short variant */
+static int add_digit_short(struct sip_request *req, char digit, unsigned int duration)
+{
+	char tmp[256];
+	int event;
+	if (digit == '*')
+		event = 10;
+	else if (digit == '#')
+		event = 11;
+	else if ((digit >= 'A') && (digit <= 'D'))
+		event = 12 + digit - 'A';
+	else
+		event = atoi(&digit);
+	snprintf(tmp, sizeof(tmp), "%d\r\n", event);
+	add_header(req, "Content-Type", "application/dtmf");
+	add_header_contentLength(req, strlen(tmp));
+	add_line(req, tmp);
+	return 0;
+}
+
 /*! \brief add XML encoded media control with update 
 	\note XML: The only way to turn 0 bits of information into a few hundred. (markster) */
 static int add_vidupdate(struct sip_request *req)
@@ -8451,6 +8477,16 @@
 	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
 }
 
+/*! \brief Send SIP INFO dtmf message in a short format */
+static int transmit_shortinfo_with_digit(struct sip_pvt *p, const char digit, unsigned int duration)
+{
+	struct sip_request req;
+
+	reqprep(&req, p, SIP_INFO, 0, 1);
+	add_digit_short(&req, digit, duration);
+	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+}
+
 /*! \brief Send SIP INFO with video update request */
 static int transmit_info_with_vidupdate(struct sip_pvt *p)
 {
@@ -10898,6 +10934,7 @@
 static struct _map_x_s dtmfstr[] = {
 	{ SIP_DTMF_RFC2833,     "rfc2833" },
 	{ SIP_DTMF_INFO,        "info" },
+	{ SIP_DTMF_SHORTINFO,   "shortinfo" },
 	{ SIP_DTMF_INBAND,      "inband" },
 	{ SIP_DTMF_AUTO,        "auto" },
 	{ -1,                   NULL }, /* terminator */
@@ -12287,6 +12324,49 @@
 		}
 		transmit_response(p, "200 OK", req);
 		return;
+	} else if (!strcasecmp(c, "application/dtmf")) {
+		unsigned int duration = 0;
+
+		get_msg_text(buf, sizeof(buf), req);
+		duration = 100; /* 100 ms */
+
+		if (!p->owner) {	/* not a PBX call */	
+			transmit_response(p, "481 Call leg/transaction does not exist", req);
+			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+			return;
+		}
+
+		if (ast_strlen_zero(buf)) {
+			transmit_response(p, "200 OK", req);
+			return;
+		}
+		event = atoi(buf);
+		if (event == 16) {
+			/* send a FLASH event */
+			struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
+			ast_queue_frame(p->owner, &f);
+			if (sipdebug)
+				ast_verbose("* DTMF-relay event received: FLASH\n");
+		} else {
+			/* send a DTMF event */
+			struct ast_frame f = { AST_FRAME_DTMF, };
+			if (event < 10) {
+				f.subclass = '0' + event;
+			} else if (event < 11) {
+				f.subclass = '*';
+			} else if (event < 12) {
+				f.subclass = '#';
+			} else if (event < 16) {
+				f.subclass = 'A' + (event - 12);
+			}
+			f.len = duration;
+			ast_queue_frame(p->owner, &f);
+			if (sipdebug)
+				ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
+		}
+		transmit_response(p, "200 OK", req);
+		return;
+
 	} else if (!strcasecmp(c, "application/media_control+xml")) {
 		/* Eh, we'll just assume it's a fast picture update for now */
 		if (p->owner)
@@ -17033,6 +17113,8 @@
 			ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
 		else if (!strcasecmp(v->value, "info"))
 			ast_set_flag(&flags[0], SIP_DTMF_INFO);
+		else if (!strcasecmp(v->value, "shortinfo"))
+			ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO);
 		else if (!strcasecmp(v->value, "auto"))
 			ast_set_flag(&flags[0], SIP_DTMF_AUTO);
 		else {
@@ -18719,6 +18801,10 @@
 		ast_clear_flag(&p->flags[0], SIP_DTMF);
 		ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
 		p->jointnoncodeccapability &= ~AST_RTP_DTMF;
+	} else if (!strcasecmp(mode,"shortinfo")) {
+		ast_clear_flag(&p->flags[0], SIP_DTMF);
+		ast_set_flag(&p->flags[0], SIP_DTMF_SHORTINFO);
+		p->jointnoncodeccapability &= ~AST_RTP_DTMF;
 	} else if (!strcasecmp(mode,"rfc2833")) {
 		ast_clear_flag(&p->flags[0], SIP_DTMF);
 		ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
Index: configs/sip.conf.sample
===================================================================
--- configs/sip.conf.sample	(revision 86631)
+++ configs/sip.conf.sample	(working copy)
@@ -126,7 +126,8 @@
 				; a valid phone number
 ;dtmfmode = rfc2833		; Set default dtmfmode for sending DTMF. Default: rfc2833
 				; Other options: 
-				; info : SIP INFO messages
+				; info : SIP INFO messages (application/dtmf-relay)
+				; shortinfo : SIP INFO messages (application/dtmf)
 				; inband : Inband audio (requires 64 kbit codec -alaw, ulaw)
 				; auto : Use rfc2833 if offered, inband otherwise
 
