mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-30 10:33:13 +00:00
send final 3 RFC2833 packets with same seqno (bug #4659)
don't reprocess incoming RFC2833 event when packets received out of order (bug #4659) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6116 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
35
rtp.c
35
rtp.c
@@ -79,6 +79,7 @@ struct ast_rtp {
|
|||||||
unsigned int lastividtimestamp;
|
unsigned int lastividtimestamp;
|
||||||
unsigned int lastovidtimestamp;
|
unsigned int lastovidtimestamp;
|
||||||
unsigned int lasteventseqn;
|
unsigned int lasteventseqn;
|
||||||
|
unsigned int lasteventendseqn;
|
||||||
int lasttxformat;
|
int lasttxformat;
|
||||||
int lastrxformat;
|
int lastrxformat;
|
||||||
int dtmfcount;
|
int dtmfcount;
|
||||||
@@ -219,7 +220,7 @@ static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char *
|
|||||||
/* process_rfc2833: Process RTP DTMF and events according to RFC 2833:
|
/* process_rfc2833: Process RTP DTMF and events according to RFC 2833:
|
||||||
"RTP Payload for DTMF Digits, Telephony Tones and Telephony Signals"
|
"RTP Payload for DTMF Digits, Telephony Tones and Telephony Signals"
|
||||||
*/
|
*/
|
||||||
static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len)
|
static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len, unsigned int seqno)
|
||||||
{
|
{
|
||||||
unsigned int event;
|
unsigned int event;
|
||||||
unsigned int event_end;
|
unsigned int event_end;
|
||||||
@@ -250,7 +251,10 @@ static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *dat
|
|||||||
f = send_dtmf(rtp);
|
f = send_dtmf(rtp);
|
||||||
} else if(event_end & 0x80) {
|
} else if(event_end & 0x80) {
|
||||||
if (rtp->resp) {
|
if (rtp->resp) {
|
||||||
|
if(rtp->lasteventendseqn != seqno) {
|
||||||
f = send_dtmf(rtp);
|
f = send_dtmf(rtp);
|
||||||
|
rtp->lasteventendseqn = seqno;
|
||||||
|
}
|
||||||
rtp->resp = 0;
|
rtp->resp = 0;
|
||||||
}
|
}
|
||||||
resp = 0;
|
resp = 0;
|
||||||
@@ -477,8 +481,23 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
|
|||||||
/* This is special in-band data that's not one of our codecs */
|
/* This is special in-band data that's not one of our codecs */
|
||||||
if (rtpPT.code == AST_RTP_DTMF) {
|
if (rtpPT.code == AST_RTP_DTMF) {
|
||||||
/* It's special -- rfc2833 process it */
|
/* It's special -- rfc2833 process it */
|
||||||
|
if(rtp_debug_test_addr(&sin)) {
|
||||||
|
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;
|
||||||
|
event_end = ntohl(*((unsigned int *)(data)));
|
||||||
|
event_end <<= 8;
|
||||||
|
event_end >>= 24;
|
||||||
|
duration = ntohl(*((unsigned int *)(data)));
|
||||||
|
duration &= 0xFFFF;
|
||||||
|
ast_verbose("Got rfc2833 RTP packet from %s:%d (type %d, seq %d, ts %d, len %d, mark %d, event %08x, end %d, duration %d) \n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp, res - hdrlen, (mark?1:0), event, ((event_end & 0x80)?1:0), duration);
|
||||||
|
}
|
||||||
if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) {
|
if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) {
|
||||||
f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
|
f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno);
|
||||||
rtp->lasteventseqn = seqno;
|
rtp->lasteventseqn = seqno;
|
||||||
} else
|
} else
|
||||||
f = NULL;
|
f = NULL;
|
||||||
@@ -988,6 +1007,7 @@ void ast_rtp_reset(struct ast_rtp *rtp)
|
|||||||
rtp->lastividtimestamp = 0;
|
rtp->lastividtimestamp = 0;
|
||||||
rtp->lastovidtimestamp = 0;
|
rtp->lastovidtimestamp = 0;
|
||||||
rtp->lasteventseqn = 0;
|
rtp->lasteventseqn = 0;
|
||||||
|
rtp->lasteventendseqn = 0;
|
||||||
rtp->lasttxformat = 0;
|
rtp->lasttxformat = 0;
|
||||||
rtp->lastrxformat = 0;
|
rtp->lastrxformat = 0;
|
||||||
rtp->dtmfcount = 0;
|
rtp->dtmfcount = 0;
|
||||||
@@ -1076,7 +1096,7 @@ int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
|
|||||||
|
|
||||||
/* Get a pointer to the header */
|
/* Get a pointer to the header */
|
||||||
rtpheader = (unsigned int *)data;
|
rtpheader = (unsigned int *)data;
|
||||||
rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++));
|
rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno));
|
||||||
rtpheader[1] = htonl(rtp->lastdigitts);
|
rtpheader[1] = htonl(rtp->lastdigitts);
|
||||||
rtpheader[2] = htonl(rtp->ssrc);
|
rtpheader[2] = htonl(rtp->ssrc);
|
||||||
rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
|
rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
|
||||||
@@ -1092,16 +1112,19 @@ int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
|
|||||||
ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr),
|
ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr),
|
||||||
ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
|
ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
|
||||||
}
|
}
|
||||||
/* Clear marker bit and increment seqno */
|
/* Sequence number of last two end packets does not get incremented */
|
||||||
rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno++));
|
if (x < 3)
|
||||||
|
rtp->seqno++;
|
||||||
|
/* Clear marker bit and set seqno */
|
||||||
|
rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno));
|
||||||
/* For the last three packets, set the duration and the end bit */
|
/* For the last three packets, set the duration and the end bit */
|
||||||
if (x == 2) {
|
if (x == 2) {
|
||||||
#if 0
|
#if 0
|
||||||
/* No, this is wrong... Do not increment lastdigitts, that's not according
|
/* No, this is wrong... Do not increment lastdigitts, that's not according
|
||||||
to the RFC, as best we can determine */
|
to the RFC, as best we can determine */
|
||||||
rtp->lastdigitts++; /* or else the SPA3000 will click instead of beeping... */
|
rtp->lastdigitts++; /* or else the SPA3000 will click instead of beeping... */
|
||||||
#endif
|
|
||||||
rtpheader[1] = htonl(rtp->lastdigitts);
|
rtpheader[1] = htonl(rtp->lastdigitts);
|
||||||
|
#endif
|
||||||
/* Make duration 800 (100ms) */
|
/* Make duration 800 (100ms) */
|
||||||
rtpheader[3] |= htonl((800));
|
rtpheader[3] |= htonl((800));
|
||||||
/* Set the End bit */
|
/* Set the End bit */
|
||||||
|
Reference in New Issue
Block a user