summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorPaul Cadach <paul@odt.east.telecom.kz>2006-09-23 18:25:13 +0000
committerPaul Cadach <paul@odt.east.telecom.kz>2006-09-23 18:25:13 +0000
commit1d50a8e881326f278e13502bf64566eb1d242641 (patch)
tree61667143a4167d561f10ab20cfa626047ab88c59 /main
parenteda44fb7ba874e9bee33247af4d956473263c0f2 (diff)
Correct behavior on Cisco's DTMF
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@43539 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/rtp.c69
1 files changed, 63 insertions, 6 deletions
diff --git a/main/rtp.c b/main/rtp.c
index 768ff4021..3ea8d3155 100644
--- a/main/rtp.c
+++ b/main/rtp.c
@@ -604,10 +604,58 @@ static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char *
unsigned int event;
char resp = 0;
struct ast_frame *f = NULL;
- event = ntohl(*((unsigned int *)(data)));
- event &= 0x001F;
+ unsigned char seq;
+ unsigned int datalen;
+ unsigned int flag;
+ unsigned int power;
+
+ /* We should have at least 4 bytes in RTP data */
+ if (len < 4)
+ return f;
+
+ /* The format of Cisco RTP DTMF packet looks like next:
+ +0 - sequence number of DTMF RTP packet (begins from 1,
+ wrapped to 0)
+ +1 (bits 7-0) - count of bytes carrying DTMF information (if DTMF
+ information repeates 3 times, i.e. packet have 6
+ bytes of DTMF information, this value equal to 6).
+ Last bit should always be zero (because DTMF info
+ is multiple of 2 bytes) but really uses as described
+ below.
+ +1 (bit 0) - flaps by different DTMF digits delimited by audio
+ or repeated digit without audio
+ +2 (+4,+6,...) - power level? (rises from 0 to 32 at begin of tone
+ then falls to 0 at its end)
+ +3 (+5,+7,...) - detected DTMF digit (0..9,*,#,A-D,...)
+ Repeated DTMF information (bytes 4/5, 6/7) is history shifted right
+ by each new packet and thus provides some redudancy.
+
+ Sample of Cisco RTP DTMF packet is (all data in hex):
+ 19 07 00 02 12 02 20 02
+ showing end of DTMF digit '2'.
+
+ The packets
+ 27 07 00 02 0A 02 20 02
+ 28 06 20 02 00 02 0A 02
+ shows begin of new digit '2' with very short pause (20 ms) after
+ previous digit '2'. Bit +1.0 flips at begin of new digit.
+
+ Cisco RTP DTMF packets comes as replacement of audio RTP packets
+ so its uses the same sequencing and timestamping rules as replaced
+ audio packets. Repeat interval of DTMF packets is 20 ms and not rely
+ on audio framing parameters. Marker bit isn't used within stream of
+ DTMFs nor audio stream coming immediately after DTMF stream. Timestamps
+ are not sequential at borders between DTMF and audio streams,
+ */
+
+ seq = data[0];
+ datalen = data[1] & ~1;
+ flag = data[1] & 1;
+ power = data[2];
+ event = data[3] & 0x1f;
+
if (option_debug > 2 || rtpdebug)
- ast_log(LOG_DEBUG, "Cisco DTMF Digit: %08x (len = %d)\n", event, len);
+ ast_log(LOG_DEBUG, "Cisco DTMF Digit: %02x (len=%d, seq=%d, repeat=%d, power=%d, history count=%d)\n", event, len, seq, flag, power, datalen / 2 - 1);
if (event < 10) {
resp = '0' + event;
} else if (event < 11) {
@@ -619,10 +667,19 @@ static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char *
} else if (event < 17) {
resp = 'X';
}
- if (rtp->resp && (rtp->resp != resp)) {
+ if ((!rtp->resp && power) || (rtp->resp && (rtp->resp != resp))) {
+ rtp->resp = resp;
+ /* Why we should care on DTMF compensation at receiption? */
+ if (!ast_test_flag(rtp, FLAG_DTMF_COMPENSATE)) {
+ f = send_dtmf(rtp, AST_FRAME_DTMF_BEGIN);
+ rtp->dtmfduration = 0;
+ }
+ } else if ((rtp->resp == resp) && !power) {
f = send_dtmf(rtp, AST_FRAME_DTMF_END);
- }
- rtp->resp = resp;
+ f->samples = rtp->dtmfduration * 8;
+ rtp->resp = 0;
+ } else if (rtp->resp == resp)
+ rtp->dtmfduration += 20 * 8;
rtp->dtmfcount = dtmftimeout;
return f;
}