>Actually, > >I believe that something is wrong with the way asterisk >implements the >whole rfc2833 in rtp.c , moreover, the default value of >100ms in >dtmf_tones[] in do_senddigit() inchannel.c is to short >to be detected >for lots of commercially available fxo gateways.
I can't agree on this. 100ms for inband DTMFs should be more than enough to detect, while for rfc2833 DTMFs even one packet can be enough, it depends on implementation. The main problem of asterisk isn't duration, but the way rtp stream is constructed. >This was reported several times but as of today the >issue is there. Seems there are a lot of other open issues concerning DTMFs in asterisk none trivial to fix. >I ended up with the following ugly hack for rtp.c & >channel.c: Increasing duration of dtmf events is not good idea. May be it force SPA-3000 to work, but this can be the source for another missfunctionalities. Please, find below my patch against 1.2.4, which makes asterisk more compliant to rfc2833 and reliable enough for SPA-3000. Index: rtp.c =================================================================== --- rtp.c (revision 10625) +++ rtp.c (working copy) @@ -1111,6 +1111,7 @@ int hdrlen = 12; int res; int x; + unsigned short duration = 0; int payload; char data[256]; char iabuf[INET_ADDRSTRLEN]; @@ -1143,7 +1144,9 @@ rtpheader[1] = htonl(rtp->lastdigitts); rtpheader[2] = htonl(rtp->ssrc); rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0)); - for (x = 0; x < 6; x++) { + + + for (x = 0; x < 5; x++) { if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them)); if (res < 0) @@ -1155,35 +1158,46 @@ ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastdigitts, res - hdrlen); } - /* Sequence number of last two end packets does not get incremented */ - if (x < 3) - rtp->seqno++; + + /* Sequence number must be incremented for every packet*/ + 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 */ - if (x == 2) { -#if 0 - /* No, this is wrong... Do not increment lastdigitts, that's not according - to the RFC, as best we can determine */ - rtp->lastdigitts++; /* or else the SPA3000 will click instead of beeping... */ - rtpheader[1] = htonl(rtp->lastdigitts); -#endif - /* Make duration 800 (100ms) */ - rtpheader[3] |= htonl((800)); - /* Set the End bit */ - rtpheader[3] |= htonl((1 << 23)); + /* Increment duration for 160 (20ms) */ + duration += 160; + rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (duration)); + } + + /* Set the End bit */ + rtpheader[3] |= htonl((1 << 23)); + + /* Send last packet and repeat it 2 times */ + for (x = 0; x < 3; x++) { + if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { + res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them)); + if (res < 0) + ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n", + ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), + ntohs(rtp->them.sin_port), strerror(errno)); + if (rtp_debug_test_addr(&rtp->them)) + ast_verbose("Sent RTP packet to %s:%d (type %d, seq %u, ts %u, len %u)\n", + ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), + ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastdigitts, res - hdrlen); } + + /* Sequence number must be incremented for every packet, even for retransmitted last two packets */ + rtp->seqno++; + /* Set seqno */ + rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno)); } + /* Increment the digit timestamp by 120ms, to ensure that digits sent sequentially with no intervening non-digit packets do not get sent with the same timestamp, and that sequential digits have some 'dead air' in between them */ - rtp->lastdigitts += 960; - /* Increment the sequence number to reflect the last packet - that was sent - */ - rtp->seqno++; + duration += 160; + rtp->lastdigitts += duration; return 0; } __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com _______________________________________________ --Bandwidth and Colocation provided by Easynews.com -- Asterisk-Users mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/asterisk-users