Hi
I ran into an issue with the way asterisk sends rfc2833 DTMF events. As my days of experience with asterisk can be counted on one hand I would like to hear your expert opinion on the attached patch that solves the problem for me, or maybe your opinion on other ways to solve the problem.
I ran into the issue using 1.0.3 on BSD, but looking at the latest rtp.c the issue is still there. I have an asterisk forwarding RTP streams between a cisco ISDN/VOIP gateway and an intel HMP. When a caller (in the PSTN) enters some DTMFs in quick succession, asterisk sends the digits without voice packets in between. That is ok, except that it re-uses the timestamp of the first digit for the following digits. The HMP box receives digits that claim to have occurred simultaneously and it ignores all but the first one. I've seen mention of this issue in some bug reports, but it seems the problem persists (CMIIW).
The cause of the issue is the fact that ast_rtp_senddigit() in rtp.c uses rtp->lastts as the timestamp. lastts is the timestamp of the latest voice packet. If no voice packets are sent, lastts does not change. The patch below uses (lastts + number of ms elapsed since then) as timestamp for sending DTMF events. The diff is against rtp.c from cvs-head.
thanks for your time.
--
mvrgr Frank van Dijk
--- rtp.c.orig 2005-02-26 04:01:11.000000000 +0100
+++ rtp.c 2005-02-26 16:47:17.854001472 +0100
@@ -1036,6 +1036,14 @@
free(rtp);
}
+static inline unsigned int timeofdaydiff_ms(const struct timeval *nw,const struct timeval *old)
+{
+ unsigned int ms;
+ ms = (nw->tv_sec - old->tv_sec) * 1000;
+ ms += (1000000 + nw->tv_usec - old->tv_usec) / 1000 - 1000;
+ return ms;
+}
+
static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
{
struct timeval now;
@@ -1047,14 +1055,12 @@
}
if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
/* Use previous txcore */
- ms = (delivery->tv_sec - rtp->txcore.tv_sec) * 1000;
- ms += (1000000 + delivery->tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
+ ms = timeofdaydiff_ms(delivery,&rtp->txcore);
rtp->txcore.tv_sec = delivery->tv_sec;
rtp->txcore.tv_usec = delivery->tv_usec;
} else {
gettimeofday(&now, NULL);
- ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
- ms += (1000000 + now.tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
+ ms = timeofdaydiff_ms(&now,&rtp->txcore);
/* Use what we just got for next time */
rtp->txcore.tv_sec = now.tv_sec;
rtp->txcore.tv_usec = now.tv_usec;
@@ -1069,6 +1075,7 @@
int res;
int x;
int payload;
+ unsigned int timestamp;
char data[256];
char iabuf[INET_ADDRSTRLEN];
@@ -1093,6 +1100,11 @@
return 0;
gettimeofday(&rtp->dtmfmute, NULL);
+
+ /* make distinct digits have distinct timestamps */
+ timestamp = timeofdaydiff_ms(&rtp->dtmfmute,&rtp->txcore) * 8
+ + rtp->lastts;
+
rtp->dtmfmute.tv_usec += (500 * 1000);
if (rtp->dtmfmute.tv_usec > 1000000) {
rtp->dtmfmute.tv_usec -= 1000000;
@@ -1102,7 +1114,7 @@
/* Get a pointer to the header */
rtpheader = (unsigned int *)data;
rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++));
- rtpheader[1] = htonl(rtp->lastts);
+ rtpheader[1] = htonl(timestamp);
rtpheader[2] = htonl(rtp->ssrc);
rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
for (x=0;x<6;x++) {
_______________________________________________ Asterisk-Dev mailing list [email protected] http://lists.digium.com/mailman/listinfo/asterisk-dev To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/asterisk-dev
