[asterisk-dev] BUGFIX: main/rtp.c bridge_p2p_rtp_write() fix inbound payload type validity check

Tony Redstone tony.redstone at googlemail.com
Fri Jun 20 11:03:54 CDT 2008


Hi,

After experiencing some upstream DTMF detection issues caused by RTP
audio and RTP telephony-event packets having different SSRC ids when
passing calls with rfc2833 signalling through an asterisk 1.4 box (sip
to sip), I believe I've tracked down the issue to the following bit of
code near the start of bridge_p2p_rtp_write():

       /* If the payload coming in is not one of the negotiated ones
then send it to the core, this will cause formats to change and the
bridge to break */
       if (!bridged->current_RTP_PT[payload].code)
               return -1;

The issue is that the code doesn't seem to match the comment.  The
value of "payload" is from the incoming RTP packet and the (struct
ast_rtp *) bridged structure is for the outbound leg so attempting to
lookup the incoming payload type in the outbound payload type array
doesn't seem to make sense.  I think the code should read:

       /* If the payload coming in is not one of the negotiated ones
then send it to the core, this will cause formats to change and the
bridge to break */
       if (!rtp->current_RTP_PT[payload].code)
               return -1;

(where rtp is the ast_rtp struct for the inbound leg)

Now the code matches the comment and also my DTMF detection problem is
resolved.  The issue occurs with 1.4 and 1.6 (but not 1.2 which uses
substantially different bridging code).

Does this fix make sense?    A patch and full explanation of the DTMF
detection problem are listed below.

Regards,
Tony

--- main/rtp.c.orig	2008-05-14 22:32:00.000000000 +0100
+++ main/rtp.c	2008-06-20 15:48:44.000000000 +0100
@@ -1063,7 +1063,7 @@
 	rtpPT = ast_rtp_lookup_pt(rtp, payload);

 	/* If the payload coming in is not one of the negotiated ones then
send it to the core, this will cause formats to change and the bridge
to break */
-	if (!bridged->current_RTP_PT[payload].code)
+	if (!rtp->current_RTP_PT[payload].code)
 		return -1;

 	/* If the payload is DTMF, and we are listening for DTMF - then feed
it into the core */



For those interested, the reason DTMF detection can be impacted is as
follows: A Thomson Speedtouch 780WL router with SIP functionality is
configured to make calls through an asterisk 1.4 box.  The speedtouch
router uses rtp payload type 97 for telephony-event.  Asterisk,
however, uses 101 for telephony-event.  When a call is originated from
the speedtouch router out through the asterisk 1.4 box to an upstream
SIP trunk, DTMF detection does not work (with an IVR application
further upstream).  If the speedtouch router is replaced with a unit
which uses payload type 101 for telephony-event, it works.  After
debugging with wireshark, the issue is because since the speedtouch
uses 97 for telephony-event, when a DTMF tone is rfc2833 signalled
from the speedtouch, the code above attempts and fails to locate
payload type 97 in the outbound bridged payload type array (which
logically would be expected) and therefore returns -1 and rtp
processing returns to ast_rtp_read().  ast_rtp_senddigit_begin() is
eventually called to insert the DTMF into the RTP stream.  At first
glance, this still looks okay but the asterisk regenerated DTMF was
not being detected further upstream.  This was because the SSRC id
used for the RTP audio and for the RTP DTMF events is now different.
For the RTP audio, the bridging code effectively copies the SSRC id
from the inbound leg whereas the SSRC id for RTP DTMF event is
asterisk's locally generated SSRC id.  Therefore, the upstream IVR
application (for example, a British Telecom call centre number) is not
processing the DTMF events (even though it is almost certainly
receiving them).  By making the change above, the bridging code now
uses the same SSRC id for both RTP audio and RTP DTMF and the upstream
IVR application works.



More information about the asterisk-dev mailing list