Up until recently Asterisk only supported RFC 4733 RTP events when using 8KHz codecs like G.711. However, with this recent change, Asterisk now supports the use of RFC 4733 digits with 8K, 16K, 24K, 32K and 48K codecs. This change required a number of changes including the concept of a “preferred codec”.
Let’s start by looking at the way Asterisk maps mime types. Generally speaking, Asterisk follows RFC 3551 when it comes to payloads. It does this by creating an association between the default id, codec and sample rate. For instance, “ast_format_ulaw” is associated with id 0 and a sample rate of 8K. Both the “PCMU” and “G711U” labels are associated with this type, but the type always defaults to id 0 and always has an 8K sample rate.
While Asterisk allows for dynamic payload types, these aspects of the type are fixed. Up until this change, “telephone-event” types were mapped similarly, defaulting to 101 with an assigned 8K sample rate. Unlike G.711 ulaw however, RFC 4733 events use a dynamic payload type. This means that while Asterisk would default to 101, if an endpoint offered a “telephone-event” payload with an id of 96 (the first dynamic type) then Asterisk would match this type.
Support for “telephone-event” payload is configured via the dtmf_mode on an PJSIP endpoint. If enabled, Asterisk would previously include this type with the fixed codec in the SDP offer or answer. Reception and generation of digits was hard-coded to the 8K sample rate. After this change, Asterisk will now look at all the other “audio” offers and will include a “telephone-event” type matching the sample rate of each offered audio codec.
This requires that Asterisk now creates an association for each of the supported sample rates, with the id assigned dynamically starting with 101.
For example, if an endpoint is configured for opus, ulaw and alaw, the SDP offer from Asterisk would look like this:
m=audio 12554 RTP/AVP 107 0 8 101 102
a=rtpmap:107 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/48000
a=fmtp:101 0-16
a=rtpmap:102 telephone-event/8000
a=fmtp:102 0-16
Note that both the ulaw and alaw offers are matched by the 102 telephone-event/8000 offer. We do not need to, nor is it correct to offer two different telephone-event 8K types.
Similarly, if the endpoint sends the following offer to Asterisk:
m=audio 4000 RTP/AVP 0 96 8 101 102
a=sendrecv
a=rtpmap:0 PCMU/8000
a=rtpmap:96 opus/48000/2
a=fmtp:96 maxplaybackrate=24000;sprop-maxcapturerate=24000;maxaveragebitrate=96000;useinbandfec=1;stereo=1
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=rtpmap:102 telephone-event/48000
a=fmtp:102 0-16
The answer should look like this:
m=audio 18898 RTP/AVP 0 96 8 101 102
a=rtpmap:0 PCMU/8000
a=rtpmap:96 opus/48000/2
a=fmtp:96 maxplaybackrate=24000;sprop-maxcapturerate=24000;maxaveragebitrate=96000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=rtpmap:102 telephone-event/48000
a=fmtp:102 0-16
Note that in each case, the 101 and 102 types are assigned dynamically based on preferred order. This brings us to the added concept of a “preferred codec”.
There is an off-nominal situation present where media may not yet be flowing between Asterisk and an endpoint. In this case we can’t know for certain which dynamic payload to use, so we opt for using the sample rate of the preferred codec as negotiated as part of SDP offer and answer to determine which to use. Realistically this is unlikely to occur, but we still handle this scenario nonetheless.
Hopefully this explains how this feature works. We look forward to your feedback!