Summary:ASTERISK-04703: [patch][post 1.4] New codec negotiation algorithm
Reporter:Andriy I Pylypenko (bamby)Labels:
Date Opened:2005-07-27 09:25:04Date Closed:2008-08-27 10:41:51
Versions:Frequency of
Environment:Attachments:( 0) asterisk.log.gz
( 1) asterisk-
( 2) asterisk-11.13.0-codec-negotiation-20141006.diff.gz
( 3) codec_negotiation-20060614.diff
( 4) codecnegotiationPatch
Description:I'm not sure is this new feature or bug fix so I'm submitting this as feature.

I did some work on codec negotiation issue. Asterisk behaves far from perfect trying to negotiate codecs while some non-installed codecs is in use (for example G723 or G729). Asterisk can transparently bridge such RTP streams but not always reasonably does codec negotiation.


1. Algorithm of codec negotiation has changed. Information about codecs passed to ast_request() & friends now processed more carefully. This functionality is very important for example for SIP channels. The following changes was made:
- In order for channels to have last chance to negotiate codecs before establishing connection the (*fixup_codecs)() callback added to ast_channel_tech structure.
- SIP channel source code was cleaned up to simplify codec management.
- Function ast_compatible_formats() was added (returns codecs that can be translated from/to given formats).

Here is example why one may need the new algorithm.

Suppose we have an Asterisk which have no G729 codec installed. One SIP UA supports G729 only. The other SIP UA supports G729 and PCMU and PCMU is preferred codec. First UA places call to second UA via Asterisk.

In the current implementation the call progress looks as follows:

UA1 -> Asterisk: INVITE UA2, codecs G729
Asterisk -> UA2: INVITE UA2, codecs A, B, PCMU, C, G729, D (all enabled in sip.conf codecs are sent)
UA2 -> Asterisk: OK, codec PCMU
Asterisk drops call with messages:

WARNING: channel.c:2333 ast_channel_make_compatible: No path to translate from ID1 to ID2
WARNING: app_dial.c:1627 dial_exec_full: Had to drop call because I couldn't make ID1 compatible with ID2

G729 codec is not present in Asterisk, so there is no way to convert it to PCMU. And we end up with call drop.

New scenario is:

UA1 -> Asterisk: INVITE UA2, codec G729
Asterisk -> UA2: INVITE UA2, codec G729
UA2 -> Asterisk: OK, codec G729
Asterisk -> UA1: OK, codec G729

So we have working connection. It has limitation that we cannot detect inband DTMF, but at least peers can talk.

Another example - UA2 invites UA1:

Current implementation:

UA2 -> Asterisk: INVITE UA1, codecs PCMU, G729
Asterisk -> UA1: INVITE UA1, codecs A, B, PCMU, C, G729, D
UA1 -> Asterisk: OK, codec G729
Asterisk drops call with the same messages as in previous example.

New diagram is:

UA2 -> Asterisk: INVITE UA1, codecs PCMU, G729
Asterisk -> UA1: INVITE UA1, codecs PCMU, G729, A, B, C (A, B, C - codecs that translateable from/to PCMU)
UA1 -> Asterisk: OK, codec G729
Asterisk -> UA2: OK, codec G729

Again we have limited but working connection.

2. The ast_channel_tech.requester() now has `const struct ast_codec_pref *' as second parameter instead of simple bitmap. This gives us generic ability to inform channel not only about formats supported but we now have chance to pass information about most preferred codec requested by peer channel (it's first in the codec set). This change is rather trivial but massive.

3. New member `bits' added to struct ast_codec_pref. Corresponding functions modified to support this field. The bits field contains bitmap of current codecs in codec set. Several functions for data manipulation in this struct were added:
- ast_codec_pref_append_missing2()
- ast_codec_pref_append_missing()
- ast_codec_pref_init() (declaration was already there, implementation added now)
- ast_codec_pref_set2()
- ast_codec_pref_combine()
- ast_codec_pref_remove2()
- ast_codec_pref_dump()
Suffix 2 in function names means that last parameter is set of codecs as bitmap.

4. Channel capability checking moved to ast_request() function and removed in channels.

5. Several bugfixes.

a) Checks like:
if (format != format_set)
replaced with
if (!(format & format_set))
b) ast_getformatname() call replaced with ast_getformatname_multiple() call when appropriate
c) In ast_codec_pref_append() function the local variable newindex was incorrectly initialized with -1 while it must be 0.
d) In ast_codec_pref_convert() function the buffer overrun prevented.
e) struct rtpPayloadType moved from rtp.c (and chan_h323.c) to rtp.h since it must be defined not only declared for chan_h323.c and chan_sip.c to compile.

P.S. I did not patch channels/chan_vpb.c as I was unable compile at least with version vpb2-2.0.3.
Comments:By: Olle Johansson (oej) 2005-07-27 12:06:59

Quick comment from a quick glance of this large patch: You need doxygen format on comments in frame.h, we're moving all documentation to doxygen. There's a readme file on that.

By: Steve Davies . (stevedavies) 2005-07-27 13:24:25

Big patch - but I'm with you on the fact that Asterisk' codec negotiation is often "suprising".  So I'd encourage the bug marshals to give this one attention!


By: Brian West (bkw918) 2005-07-29 08:50:18

This will have to be tested REALLY WELL before it can go in.  The codec negociation stuff works fine as it is if you understand it.  I suspect alot of people just don't understand how it works.  And you can't init the pref at 0 you must do -1, because the codec index starts at 0 and goes up.


By: tomyoung (tomyoung) 2005-07-29 22:41:39

I got compiled error:

gcc -pipe  -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g  -Iinclude -I../include -D_REENTRANT -D_GNU_SOUR
CE  -O6 -march=i686  -DZAPTEL_OPTIMIZATIONS          -fomit-frame-pointer  -Wno-missing-prototypes -Wno-missing-declarations   -DZAP
ATA_PRI   -DIAX_TRUNKING   -DCRYPTO -fPIC    -c -o chan_oss.o chan_oss.c
chan_oss.c:141: warning: initialization from incompatible pointer type
chan_oss.c: In function `oss_new':
chan_oss.c:759: incompatible types in assignment
make[1]: *** [chan_oss.o] Error 1
make[1]: Leaving directory `/usr/src/20050727/asterisk/channels'
make: *** [subdirs] Error 1

By: Olle Johansson (oej) 2005-07-30 07:12:43

I think it's too late to implement this large a change in 1.2, we have to look at it for 1.3 dev.

By: Andriy I Pylypenko (bamby) 2005-08-01 02:21:54

Oops, I missed chan_oss somehow...
Here is updated patch using fresh cvs HEAD version (comments in frame.h are also updated).

P.S. chan_h323 is broken now (not by me :-) ):

gcc -pipe  -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g  -Iinclude -I../include -I/usr/local/include -D_REENTRANT -D_GNU_SOURCE  -O6 -march=i386   -I/usr/local/include/spandsp  -DZAPTEL_OPTIMIZATIONS         -fomit-frame-pointer  -Wno-missing-prototypes -Wno-missing-declarations  -DOLD_SANGOMA_API     -DIAX_TRUNKING  -DCRYPTO -fPIC    -c -o chan_h323.o chan_h323.c
chan_h323.c: In function `oh323_alloc':
chan_h323.c:827: error: structure has no member named `newsignal'
chan_h323.c: In function `update_state':
chan_h323.c:877: error: structure has no member named `newsignal'
chan_h323.c: In function `connection_made':
chan_h323.c:1212: warning: unused variable `c'
chan_h323.c: In function `chan_ringing':
chan_h323.c:1414: warning: unused variable `c'
gmake[1]: *** [chan_h323.o] Error 1
gmake[1]: Leaving directory `/usr/home/bamby/src/asterisk2/channels'
gmake: *** [subdirs] Error 1

By: mihai (mihai) 2005-08-05 12:26:37

I tried both versions of the patch and both are failing to apply to today's (8/5) HEAD tree.  codec_negotiation.diff fails one hunk in rtp.c, the other file fails multiple times. Of course, compilation fails after that, in rtp.c:
rtp.c:1496: error: structure has no member named `get_codec'
rtp.c:1497: error: structure has no member named `get_codec'
rtp.c:1500: error: structure has no member named `get_codec'
rtp.c:1501: error: structure has no member named `get_codec'
rtp.c:1504: error: structure has no member named `get_codec'
rtp.c:1504: error: structure has no member named `get_codec'

Could you please post an updated patch? Or please let me know if I'm doing something wrong...


PS: correct codec negotiation was long overdue :)

By: Andriy I Pylypenko (bamby) 2005-08-05 13:15:54

Yes changes in rtp.c and chan_oss.c caused conflicts. So here is fresh version of patch.

By: mihai (mihai) 2005-08-05 14:02:20

Still got some problems...  The patch applies now, but it breaks the compile in chan_phone.c:

chan_phone.c:154: warning: initialization from incompatible pointer type
chan_phone.c:168: warning: initialization from incompatible pointer type
chan_phone.c: In function `phone_new':
chan_phone.c:792: error: incompatible types in assignment
chan_phone.c:797: error: incompatible types in assignment
chan_phone.c:801: error: incompatible types in assignment

UPDATE: apparently what needs to be changed is tmp->nativeformats should be tmp->nativeformats.bits.

The code compiles and works fine after that :)


By: Andriy I Pylypenko (bamby) 2005-08-09 07:31:15

In this case bits is modified but you cannot do this directly. You have to use appropriate ast_codec_pref_append*() call.
Here is new patch including changes to chan_phone.c and two more conficts in rtp.c and channel.c resolved.

By: mihai (mihai) 2005-08-24 11:45:18

Today's HEAD breaks the patch (in chan_sip.c). Could you please reissue?

By: Andriy I Pylypenko (bamby) 2005-08-25 05:59:03

Fresh version of patch with conflicts in chan_sip.c resolved.

By: mihai (mihai) 2005-08-31 13:20:37

CVS head breaks the patch again (in chan_sip.c)....

By: Vladimir Klejch (kleo) 2005-09-01 09:02:51

Im testing patch from 08-25-05 05:58 an it is working very good. But i have problem with reinvite with sdr for codec change with incomming fax ...

The scenario is:
UA2 -> Asterisk: INVITE UA1, codecs G729, PCMA, PCMU
Asterisk -> UA1: INVITE UA1, codecs G729, PCMA, PCMU,  gsm, B, C
UA1 -> Asterisk: OK, codec G729
Asterisk -> UA2: OK, codec G729

conection * -> UA2 OK (G729), connection  * -> UA1 OK (G729)
and after 10 sec UA1 (Linksys RT31P2) have recognised incomming fax and:

UA1 -> Asterisk: INVITE UA2, codec PCMA
Asterisk -> UA1: OK , codec PCMA
conection * -> UA2 OK (G729), connection  * -> UA1 OK (PCMA)

* is doing transcoding,  after 30 sec BYE from UA2 (fax offhook).

With G729 is not posible send fax, but  with PCM[AU] its posible.
Asterisk should send INVITE to UA2 after codec change from UA1, and don't transcode.

It's probably global Asterisk problem. I don't know a what to do to force asterisk to send reinvite after codec change and don't transcode.


By: Andriy I Pylypenko (bamby) 2005-09-13 09:48:29

Here is at last the new version of patch. Now with reinvites working :-)

By: Andriy I Pylypenko (bamby) 2005-09-13 09:56:53

Couple words on new changes - set_rtp_peer() callback now receives ast_codec_pref structrure to keep track of most preferred codec so to do reinvite correctly. Furthermore Asterisk now reinvites not only with new peer channel codecs but also offers all compatible with them codecs (just in case the reinvited UA doesn't support codecs offered by the requesting UA).

By: Andrew Lindh (andrew) 2005-09-13 15:06:42

I tested today's patch. No problem installing on CVS HEAD (even with some other patches added). But it caused a failure for me.

Calling from a phone allowing only g.729 going out using an AS5300 with all codecs allowed and the call makes progress an then I get an error (and no audio):
WARNING: chan_sip.c: 2441 sip_write: Asked to transmit frame type 4, while ative formats is 256 (read/write = 256/256)

It turns out the as5300 refuses the g.729 stream and then the call audio fails....I have the digium g.729 codec installed and working, so asterisk should fallback to transcoding.

By: Andriy I Pylypenko (bamby) 2005-09-14 03:09:32

2andrew: I have no g729 codec to test but I tested with G711U/G711A transcoding. Asterisk falls back to transcoding without problems. Please describe in detail what's going on in your case (sip debug log for example).
Also pay attention to output of 'show translations' command. It must contain digits in g729 column and row. If there are dashes only in that column and row then transcoding will not work.

By: Andriy I Pylypenko (bamby) 2005-09-23 09:30:19

Here is the new version of patch. Things added:
1. Small fix to reinvite.
2. Allow to send/receive RTP traffic in multiple codecs even they all require translation.

By: Andrew Lindh (andrew) 2005-09-23 11:00:39

The new patch is different....better but wrong.

Example. Three devices: (plus asterisk in the middle)
301: supports ulaw+g729
310: allows g729 (by sip.conf, phone does support ulaw but should not use it)
as5300: allows ulaw+g729 (but g729 is broken and rejects media)

WITHOUT the patch, calls from 310 to 301 use g729 as expected on both ends.
Calls from 301 to 310 use ulaw and asterisk translates to g729, not good as 301 should have been re-invited to use g729, but the call works.
Calls to as5300 use ulaw directly or asterisk translates from g729 to ulaw
because that's all the as5300 will actually accept.

WITH the patch, g729 calls to as5300 are correctly translated by asterisk as the as5300 rejects g729. This did not seem to work with the last patch version.

Calls from 310 to 301 use g729 as expected. They worked before and now.

BUT it's the call from 301 to 310 that should work better....but there is a bug. The calls NOW (with patch) use ulaw. Is this ok? NO! They are both using the same codec as the phone HARDWARE supports it, but the sip.conf listed to limit the calls to g.729 ONLY on x310.....but the caller (using ulaw) forced the callee (310) to be re-invited with ulaw. In this case the calling phone (301) should have been reinvited or limited to g729 for the call TO 310 (g729 only by sip.conf). Same thing for calls from the as5300 (ulaw only working) to 310 (limited to g729 by sip.conf, but supports ulaw). In this case asterisk should have translated from ulaw to g.729 rather than re-invite 310 using ulaw.

So it worked, but in bad forceful way. It matched the codec when it could but it went around the asterisk config to do so.

When it "works" a "sip show channels" says "unknown" for the caller's codec
and the callee's codec is ulaw.

(yes, I do have the real digium g729 asterisk codec installed and working)

By: mihai (mihai) 2005-09-30 09:58:33

CVS Head breaks the latest version of the patch... any chance you could reissue?
Also, I have the feeling that the patch disables video codecs (H263), but I couldn't test with the latest version....


By: Denis Voitenko (denis) 2005-09-30 19:16:37

The forceful decision making process seems a bit too daring. I belive it'd be smarter to allow the configuration file decide what logic is followed when deciding which codec to use. Please see bug 5347 for my description.

By: Andriy I Pylypenko (bamby) 2005-11-07 10:21:08.000-0600

What's new in the new version:

1. The configuration parameter "translation_algorithm" added to asterisk.conf, the [codec_negotiation] section. Please see the asterisk.conf for further description (it can be created by "make samples").
2. Multicodec translations was extensively tested and several bugs fixed. Multicodec translation enables faxing in non-reIVITE mode when UA switches from LBR codec to G711 codec on the fly without the reINVITE just after the CNG tone has been detected (for example - Sipura UA in NSE mode).

2andrew: Regarding the diagram (I assume it as follows as at least the Sipura UA does it in such way):

UA310 -> Asterisk: INVITE G729, ULAW
Asterisk -> UA301: INVITE G729, ULAW
UA301 -> Asterisk: OK ULAW
Asterisk -> UA310: OK G729 (sip.conf disables sending the ULAW in OK)
you suggest reinvite to G729 here

I see the problem here: Asterisk cannot know for sure that UA301 supports G729. So the full algorithm I see as follows - Asterisk invites UA301 with G729 codec only first and if invite fails the Asterisk tries to invite UA301 with full set of codecs.

Both behaviours (with and without reinvite) are correct in certain situations and I think there are several more similar situations and behaviours. For example suppose the UA1 supports ULAW and UA2 supports G729 and ULAW with ULAW configured as preferred codec and our main goal is to save network traffic regardless of CPU utilization. The UA2 obviously should be invited with G729 only first despite of lack of G729 in initial invite. And so on and so on.

I think there should be some configuration parameter to choose between algorithms based on bandwidth and CPU consumption to choose optimal codec configuration. I'll try to implement this when I have some spare time. Currently you can try to use the "translation_algorithm" parameter that can be a solution in some cases.

2denis: the "translation_algorithm" parameter can be temporary solution for 5347 .

P.S. I haven't fixed the "sip show channels" issue yet.

By: mihai (mihai) 2005-12-27 09:01:52.000-0600

Could you please issue a patch against 1.2.1 ?
It is unfortunate that this did not make it into stable yet...


By: mihai (mihai) 2006-01-11 12:36:02.000-0600


Is this thread dead? Is anybody still interested in this?

By: hcb (hcb) 2006-01-12 04:08:28.000-0600

I am very intrested in this feature :)


By: Vladimir Klejch (kleo) 2006-01-13 07:29:19.000-0600

I am very intrested in this feature too, i am using this feature in 4 servers. I hope, this get in CVS.


By: mihai (mihai) 2006-01-16 08:41:05.000-0600

I was wondering if the original author of this patch is still available and interested in further developing it.  It would be a pitty to let this one slide... especially since it is apparently useful to a number of people (myself included). So bamby: are you still there? If you're no longer interested in this project please let us know. Someone else could continue your work...


By: Andriy I Pylypenko (bamby) 2006-01-17 10:28:27.000-0600

I tried to make the new version of the patch today but with the transition of the repository to subversion a lot of manual patching is required so I'll upload it within two days.
I didn't make the patch against the 1.2.x version and I'm not going to in the meantime.

By: Andriy I Pylypenko (bamby) 2006-01-18 08:30:00.000-0600

I'm uploading the fresh patch.

It now also implements the codec negotiation during early audio phase (SIP response with code 183). This is important for certain SIP<->zaptel bridge configurations.

By: mihai (mihai) 2006-01-18 10:02:28.000-0600

Is the new patch created against the 1.2 branch or against trunk? If it is against trunk, do you have any plans of releasing a patch against the 1.2 branch?


By: Andriy I Pylypenko (bamby) 2006-01-20 08:02:51.000-0600

This is the patch against trunk. No patch for 1.2 is available now.

By: mihai (mihai) 2006-01-20 08:53:17.000-0600

Is there any chance you could issue a patch against the 1.2 branch? Or at least against the released versions of 1.2 (1.2.2 as of now). I know it is a pain to maintain multiple code branches, so let me know if there's anything I can do to help...


By: Andriy I Pylypenko (bamby) 2006-01-25 07:12:05.000-0600

I'm uploading the fresh patch for trunk.

There are good news for people who want to use this patch with asterisk-1.2.2. You can download it here:


By: Andriy I Pylypenko (bamby) 2006-01-31 09:16:06.000-0600

Fresh patch with fix in ast_channel_make_compatible.

By: paolo (paolo23) 2006-02-01 10:29:14.000-0600

Hi all,
I have Asterisk 1.2.3 installed on linux fedora core4.
I have many problem with codec from sip softphone so i decided to install the last patch available.
I install it using the command patch:
# patch --verbose -i asterisk123_codec...... . diff
all was good without any errors.
Then i execute the command make in the asterisk dir but I have some errors as I reported in the file errori_make_asterisk.txt that I submit.
Someone can help me?

By: mihai (mihai) 2006-02-01 10:49:14.000-0600

paolo: I'm running Asterisk 1.2.4 with the 1.2.3 version of the patch without any problems. Make sure you get the 123 version of the patch from bamby's website - see comments. The versions that are posted here are diffed against the development (trunk) tree.
Then unpack asterisk, go to asterisk-1.2.4 directory and do a

zcat <path to the 123 patch>.gz | patch -p0

The patch should apply with no errors. Then compile asterisk normally . You might get a few warnings, but bo errors. If this doesn't work, then it could be that there is something stramge with your Fedora installation.

By: paolo (paolo23) 2006-02-02 04:07:24.000-0600

Thank you mihai. Now i've correctly installed the patch with only some warnings.
I tested immediately if the patch works correctly and i have much more errors then before.
I made a call from my "Adoresoft" sip softphone.

My configuration:

exten => 333,1,Answer
exten => 333,2,NVBackground(welcome)
exten => 333,3,Hangup

Here there is the error:

*CLI>     -- Registered SIP '5500' at port 10591 expires 120
   -- Saved useragent "RTC/1.2.4949" for peer 5500
   -- Executing Answer("SIP/5500-cb73", "") in new stack
   -- Executing NVBackgroundDetect("SIP/5500-cb73", "welcome") in new stack
Feb  2 11:47:02 WARNING[9278]: channel.c:2320 set_format: Unable to find a codec translation path from 0x1 (g723) to slin
Feb  2 11:47:02 WARNING[9278]: channel.c:2320 set_format: Unable to find a codec translation path from 0x1 (g723) to gsm
Feb  2 11:47:02 WARNING[9278]: translate.c:132 ast_translator_build_path: No translator path from g723 to unknown
Feb  2 11:47:02 WARNING[9278]: chan_sip.c:2530 sip_write: Asked to transmit frame type 2, while native formats is 1 (read/write = 64/2)
   -- Playing 'welcome' (language 'en')
   -- Executing Hangup("SIP/5500-cb73", "") in new stack
 == Spawn extension (context-incoming, 333, 3) exited non-zero on 'SIP/5500-cb73'

It's only a problem with my configuration? Or i missed something? I didn't hear the voice. Someone can help me please?

By: Andriy I Pylypenko (bamby) 2006-02-02 09:10:55.000-0600

Fresh patch against trunk and 1.2.4

Changes overview:

- bugfix in ast_request function
- fix for 'sip show channels', 'sip show channel' and 'show channel' commands to show correct information about codecs
- fix for asterisk to follow the RFC3551 more carefully in processing dynamic RTP payload types

The latter problem is as follows.
When the UA sends SDP with codec unknown to asterisk with dynamic payload type that by accident equals to one of the values from the static_RTP_PT array the asterisk mistakenly assumes the unknown codec to be in fact the one from its internal array. This algorithm has been left untouched for static payload types and prevented for dynamic ones. Dynamic types now can only be recognized by their MIME types.

By: Andriy I Pylypenko (bamby) 2006-02-02 09:27:50.000-0600

2paolo: From the error message I may assume that you don't have the g723 codec installed. If so then you can use some of the default asterisk codecs that are opensource: ALAW, ULAW, G726-32, iLBC, speex, GSM, LPC or even L16 ;-)

By: jeds (jeds) 2006-02-03 20:58:27.000-0600

heads up, once patch is applied in 1.2.4, ooh323c appears to break during compile.

source='src/chan_h323.c' object='chan_h323.lo' libtool=yes \
depfile='.deps/chan_h323.Plo' tmpdepfile='.deps/chan_h323.TPlo' \
depmode=gcc3 /bin/sh ./config/depcomp \
/bin/sh ./libtool --mode=compile gcc -DHAVE_CONFIG_H -I. -I. -I. -I./ooh323c/src -I./ooh323c/src/h323    -DGNU -D_GNU_SOURCE -D_REENTRANT -D_COMPACT -c -o chan_h323.lo `test -f 'src/chan_h323.c' || echo './'`src/chan_h323.c
mkdir .libs
gcc -DHAVE_CONFIG_H -I. -I. -I. -I./ooh323c/src -I./ooh323c/src/h323 -DGNU -D_GNU_SOURCE -D_REENTRANT -D_COMPACT -c src/chan_h323.c -MT chan_h323.lo -MD -MP -MF .deps/chan_h323.TPlo  -fPIC -DPIC -o .libs/chan_h323.lo
src/chan_h323.c:68: warning: initialization from incompatible pointer type
src/chan_h323.c:87: warning: initialization from incompatible pointer type
src/chan_h323.c: In function `ooh323_new':
src/chan_h323.c:255: error: incompatible types in assignment
src/chan_h323.c:258: error: incompatible type for argument 1 of `ast_best_codec'
src/chan_h323.c: In function `ooh323_write':
src/chan_h323.c:882: error: invalid operands to binary &
src/chan_h323.c: In function `ooh323_rtp_read':
src/chan_h323.c:3042: error: invalid operands to binary !=
src/chan_h323.c:3045: error: incompatible types in assignment
make[1]: *** [chan_h323.lo] Error 1

By: jeds (jeds) 2006-02-04 01:50:34.000-0600

Hoping to understand flow better. I'm having an issue with DTMF and wonder if it is expected. We have an incoming call hit our server which includes G729 and ULAW in the invite. With the patch installed we then send an invite to our client's server saying G729 and ULAW. They reply back with G729 only and the call connects with G729 nicely with this patch installed.

We get a couple of screen warnings about not being able to convert from ulaw to g729 that look like this:

"channel.c:2320 set_format: Unable to find a codec translation path from 0x4 (ulaw) to g729"

But the call connects fine with G729 aside from that. However DTMF does not work no matter what combination of options I set for DTMFMODE. If they set their side to ulaw and connect that way it will work. We've tried forcing all sides to rfc2833, auto, etc and all possible combinations we could think of as well with no luck. Any thoughts?

By: pj (pj) 2006-02-04 09:42:26.000-0600

I had also problem with DTMF passing through ooh323, but even without this patch, maybe general ooh323 issue? currently using oh323 without problems...

By: jeds (jeds) 2006-02-04 14:28:47.000-0600

I guess I should have clarified, the DTMF issue is with SIP. The ooh323c issue is seperate.

By: Andriy I Pylypenko (bamby) 2006-02-06 05:13:48.000-0600

Yes this is known issue that third party channel drivers are broken after this patch has been applied but it's generally no problem to fix this as the changes are quite simple and straitforward.

Regarding the DTMF. The routine that extracts the DTMF from the voice stream acts on SLINEAR data so the voice stream has to be converted to SLINEAR first for the DTMF to be detected. If you use G729 or G723 format for voice without corresponding asterisk's commercial codec module installed the asterisk has no ability to do the conversion. So you have to use the RFC2833 DTMF in your UA or install the commercial codec module or use some other voice format (not G72[39]).

By: tom (tom) 2006-02-13 02:46:12.000-0600

I've 2 sip-based video phones(v1 v2). There's some problem with my phones with this feature.

v1->asterisk SDP:
m=audio 7078 RTP/AVP 8 0 4 101
a=rtpmap:8 pcma/8000/1
a=rtpmap:0 pcmu/8000/1
a=rtpmap:4 g723/8000/1
a=rtpmap:101 telephone-event/8000/1
m=video 7080 RTP/AVP 34
a=fmtp:34 CIF=1 QCIF=1/MaxBR=3840

asterisk->v2 SDP:
m=audio 15424 RTP/AVP 8 0 3 101
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:3 GSM/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=silenceSupp:off - - - -

2 problems with this SDP:
- video media line missed
- G723 (payload type is 4) is replaced by GSM(3)

By: tom (tom) 2006-02-13 03:20:10.000-0600

both phones configure:

By: J.R. (jrast) 2006-02-15 13:16:34.000-0600

I've been having problems with this patch, and now have a further patch as a solution to my problem.

My A* server is behind a NAT firewall, with local phones on the internal network, and a number of SIP peers on the outside.  The firewall is configured to allow (using a firewall redirect) RTP in to the phones' subnet so that RTP reinvites should work.  The problem I was seeing was that the RTP reinvites were sending a phone's internal address to an outside peer which obviously meant that subsequent RTP from the external peer was not coming back home; the outbound was OK, though, so I had one-way audio.

A* is configured in sip.conf with an externip and localnet statements.  All the external peers are configured with nat=yes while the internal users have nat=no.

The following patch is necessary to make things work.  This applies on top of the codec_nego patch; I've done this using A* 1.2.4.

The first part of this patch (rtp.c) fixes a bug that is probably a problem for everyone using 1.2.4.

The second part (channels/chan_sip.c) is the change for my RTP redirect problem.

--- rtp.oc  Tue Feb 14 16:12:26 2006
+++ rtp.c   Tue Feb 14 16:15:51 2006
@@ -1589,7 +1589,7 @@
       codec0 = c0->nativeformats.bits;
       codec1 = c1->nativeformats.bits;
       memcpy(&codecs0, &c0->nativeformats, sizeof(codecs0));
-       (&codecs1, &c1->nativeformats, sizeof(codecs1));
+       memcpy(&codecs1, &c1->nativeformats, sizeof(codecs1));
       /* Hey, we can't do reinvite if both parties speak different codecs */
       if (!(codec0 & codec1)) {
               if (option_debug)
--- channels/chan_sip.oc    Tue Feb 14 16:12:26 2006
+++ channels/chan_sip.c     Wed Feb 15 14:48:19 2006
@@ -4372,8 +4372,15 @@
               ast_rtp_get_us(p->vrtp, &vsin);

       if (p->redirip.sin_addr.s_addr) {
+               if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) {
+                       struct in_addr our_ip;
+                       if (!ast_sip_ouraddrfor(&p->sa.sin_addr, &our_ip))
+                               memcpy(&dest.sin_addr, &our_ip, sizeof(dest.sin_addr));
+                       else
+                               dest.sin_addr = p->redirip.sin_addr;
+               } else
+                       dest.sin_addr = p->redirip.sin_addr;
               dest.sin_port = p->redirip.sin_port;
-               dest.sin_addr = p->redirip.sin_addr;
                if (p->redircodecs.bits) {
                        /* We are to get all compatible with redircodecs codecs */
                       capability = &p->redircodecs;

By: tom (tom) 2006-02-16 20:18:24.000-0600

The 1st problem (video media line missed) : I found the H263 format is removed in channel.c ast_request() by ast_codec_pref_remove2()
The 2nd problem (G723 is replaced by GSM) : This is my configuration mistake. I should configure allow=g723.1
And I found probably a mistake in chan_sip.c as shown below.

I'm a beginner of asterisk, could someone help me to solve the 1st problem properly?

*** channel.c.o Fri Feb 17 10:47:21 2006
--- channel.c   Fri Feb 17 10:48:32 2006
*** 2499,2501 ****
               memcpy(&tmp_formats, &formats, sizeof(formats));
!               ast_codec_pref_remove2(&tmp_formats, ~chan->tech->capabilities);
               if (!(c = chan->tech->requester(type, &tmp_formats, data, cause)))
--- 2499,2501 ----
               memcpy(&tmp_formats, &formats, sizeof(formats));
!               //ast_codec_pref_remove2(&tmp_formats, ~chan->tech->capabilities);
               if (!(c = chan->tech->requester(type, &tmp_formats, data, cause)))
*** channels/chan_sip.c.o       Fri Feb 17 10:47:44 2006
--- channels/chan_sip.c Fri Feb 17 10:48:53 2006
*** 4457,4459 ****

!               if (x <= AST_FORMAT_MAX_AUDIO)
                       add_codec_to_sdp(p, pref_codec, 8000,
--- 4457,4459 ----

!               if (pref_codec <= AST_FORMAT_MAX_AUDIO)
                       add_codec_to_sdp(p, pref_codec, 8000,

PS: could someone tell me how to have the diff output format as shown in bamby and jrast's notes? Thanks.

By: tom (tom) 2006-02-17 02:17:23.000-0600

Both my phones are sending RFC2833 DTMF. As I tested, Asterisk1.2.4 can handle DTMF. While with this patch, it can only farward caller DTMF to callee, but can't forward callee DTMF to caller.

By: tom (tom) 2006-02-17 03:24:12.000-0600

All my testing (video line missing, 1-way DTMF) is done with Asterisk1.2.4

By: J.R. (jrast) 2006-02-17 11:48:18.000-0600

Below is an update to my patch.  What I posted before can be simplified slightly - I was looking up again an IP address that is already available, so I may as well just use the stored value.

I also found another bug which is pretty critical - in sip_set_rtp_peer(), redircodecs was being set from the other channel's values, but a bit further down, redircodecs was being cleared again!  So during the subsequent redirect negotiation, they weren't actually being given each other's codec choices.  This is fixed by removing the unnecessary clearing of redircodecs.

Tom: I agree with your change on channels/chan_sip.c:4459, replacing "x" with "pref_codec", so you'll also see that change included here, now.

Here's the patch again... for 1.2.4, applies on top of bamby's codec_nego patch.

--- rtp.oc      Tue Feb 14 16:12:26 2006
+++ rtp.c       Tue Feb 14 16:15:51 2006
@@ -1589,7 +1589,7 @@
       codec0 = c0->nativeformats.bits;
       codec1 = c1->nativeformats.bits;
       memcpy(&codecs0, &c0->nativeformats, sizeof(codecs0));
-       (&codecs1, &c1->nativeformats, sizeof(codecs1));
+       memcpy(&codecs1, &c1->nativeformats, sizeof(codecs1));
       /* Hey, we can't do reinvite if both parties speak different codecs */
       if (!(codec0 & codec1)) {
               if (option_debug)
--- channels/chan_sip.oc        Tue Feb 14 16:12:26 2006
+++ channels/chan_sip.c Fri Feb 17 13:22:28 2006
@@ -4373,7 +4373,10 @@

       if (p->redirip.sin_addr.s_addr) {
               dest.sin_port = p->redirip.sin_port;
-               dest.sin_addr = p->redirip.sin_addr;
+               if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)
+                       dest.sin_addr = p->ourip;
+               else
+                       dest.sin_addr = p->redirip.sin_addr;
                if (p->redircodecs.bits) {
                        /* We are to get all compatible with redircodecs codecs */
                       capability = &p->redircodecs;
@@ -4456,7 +4459,7 @@
               if (alreadysent & pref_codec)

-               if (x <= AST_FORMAT_MAX_AUDIO)
+               if (pref_codec <= AST_FORMAT_MAX_AUDIO)
                       add_codec_to_sdp(p, pref_codec, 8000,
                                        &m_audio_next, &m_audio_left,
                                        &a_audio_next, &a_audio_left,
@@ -12756,7 +12759,6 @@
       /* Reset lastrtprx timer */
-        ast_codec_pref_init(&p->redircodecs);
       return 0;

Tom: this is "diff -u" format, by the way.

Tom: I'm not sure about your channel.c change, although I haven't really had time to consider it properly.

By: Serge Vecher (serge-v) 2006-02-17 12:28:00.000-0600

jrast: any chance you could incorporate your changes into bamby's patch and release a single diff?

By: J.R. (jrast) 2006-02-18 20:26:48.000-0600

Vechers: Eventually, sure, or maybe Bamby will incorporate what I've done into the next version of the patch.

But at the moment, I am looking at two more issues.  Bamby, if you're there, maybe you can comment on these.  Or anyone else...

Issue the First is that the code to save the received codecs at channels/chan_sip.c:3586 calls ast_rtp_lookup_pt() to make sure the codec is supported by A*.  However, as it stands, that function ignores payload types 96..127 (the dynamic ones).  What this means is that we will never consider iLBC, H263+, speex or G726 during the pre-negotiation (i.e., when trying to decide if the two parties have any codecs in common).  Now, the rtp_lookup_pt() function does an additional test which seems to include these codecs if rtp_offered_from_local is false, however that isn't the case when we're calling rtp_lookup_pt().  I think a further patch is needed to make rtp_offered_from_local true at the point we're doing this.  Either that, or we need to add a separate test for these codecs.  I am still working on this.

Tom: the above might have something to do with why you're losing H263, too.

Issue the Second is that when we offer each party the redir invite (in channels/chan_sip.c:4446, we should NOT be sending all the codecs in our userprefs again.  At this stage, we already know that both parties do have codecs in common, so all we should send each party this time is the codecs the other party has.  The patch for this is easy, but I'll hold off sending it until I have a complete patch including the First issue, too.

File/line refs are again for 1.2.4 with both the codec_nego patch and my additional patch applied.

By: J.R. (jrast) 2006-02-19 08:53:54.000-0600

I'm uploading a new version of my additional patches which address the issues I posted last night.  To address the issue that codecs in the dynamic 96..127 range are ignored, I'm just forcing rtp_offered_from_local to false at the point where we process SDP info.  This may not be appropriate every time, but seems to work for me.  In the light of feedback from folk here, I may need to adjust this.

Since the patch is now getting longer, I'm uploading it as a file attachment on this thread: asterisk124-additional_patch.diff.

Sorry, I don't have a version against asterisk current/trunk.

To apply for 1.2.4, apply Bamby's asterisk124_codec_negotiation-20060202_1.diff patch first, then apply my asterisk124-additional_patch.diff.

Feedback is appreciated, especially on the rtp_offered_from_local change.

If folk think these additional changes are OK, perhaps Bamby, you could include these in your main patch?

By: J.R. (jrast) 2006-02-19 10:14:10.000-0600

OK, I also made a version of my additional patches against asterisk-current.  See attached file asterisk-cur-additional_patch_jr.diff.

By: tom (tom) 2006-02-19 20:47:26.000-0600

Thanks for your supports. jrast.

As to Issue2(jrast's notes), consider this scenario, sip-based phone1 supports H261, phone2 supports both H263++ and H261, and phone2 prefers H263++ in its invite SDP (peerprefs). If possible,I think everyone would avoid video transcoding since it employs much more resources than voice transcoding. This is why this new feature attracts me. It is very useful in this scenario. Because without this patch, video transcoding is necessary, otherwise all phone2s have to downgrade to H261 only.

But even with this patch, the admin still have to config video codecs preference properly on Asterisk (userprefs), because this patch only considers the 1st peerpref, normally this is audio codec (99.99% pbone place audio line first). I think it conflicts with this feature's philosophy. Do the folk agree on this? The fix is easy, to send all peerprefs in its order at first, then all userprefs. It only needs to change chan_sip.c add_sdp().

Some advanced phone may send reinvite to change exsiting media session. I wonder how this does with Asterisk and with Issue2?

By: J.R. (jrast) 2006-02-20 08:22:05.000-0600

Tom: two things.

I've found that, with these patches, I do not need to specify any codec disallow/allow statements in sip.conf for any user/peers.  I do specify some under [general], but even there, merely "allow=all" now works fine.  Essentially, this means I am always relying on each party to give me their codecs in their SDP, which is how it should be.

Now, if you do specify codecs for users/peers in your sip.conf, and do not use my additional patch, the codecs that are specified in sip.conf for each party are resent (from userprefs) back to that party during the reinvite which would allow your phone2 to choose any of its own codecs; this means it will choose H263+ since that is its preferred codec, and this in turn means A* will then have to transcode.  However, if you do use my additional patch, during the reinvite the codecs from sip.conf are not resent, so phone2 will only receive the H261 from phone1, which means phone2 will have to choose H261, and there'll be no transcoding.

So, I think what you want is to either remove the codecs from the user/peers in sip.conf, or use my additional patch.

If this doesn't help, perhaps you could be more specific about exactly what you have in sip.conf, what you're seeing in the SDPs (for both initial and reinvites) and what versions of A* and which patches you're using.

By: jeds (jeds) 2006-02-20 14:53:18.000-0600

Tom, any luck getting DTMF working both ways with this patch? This has become a real issue for us.


By: tom (tom) 2006-02-20 22:26:49.000-0600

jeds: this is because A* can't recognize callee's payloadtype 101 (dynamic pt) as telephone event. I will try. And I think it is related to Issue1. I’ll try jrast’s patch first when I have time. Hope it can fix this problem.

jrast: yes, “allow=all” should work well. It can release the admin from heavy work. While I consider the following, if the admin mis-config
Phone1: allow=ulaw&alaw&H261
Phone2a: allow=ulaw&alaw&H261&H263+          (wrong config)
Phone2b: allow=ulaw&alaw&H263+&H261 (right config)
When phone2a call phone2b, phone2b may choose H261 since it’s the 1st video codec in the invite SDP. Certainly phone2b can also choose H263+. It depends on how the engineer designs phone2. The result is uncertain. But if change the code:
--- channels/chan_sip.oc        Tue Feb 21 11:09:08 2006
+++ channels/chan_sip.c Tue Feb 21 13:18:10 2006
@@ -4410,8 +4410,14 @@
       ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));

       /* Prefer the codec we were requested to use, first, no matter what */
-       pref_codec = ast_codec_pref_index(capability, 0);
-       if (pref_codec) {
+       for (x = 0 ; x < 32 ; x++) {
+               if(!(pref_codec = ast_codec_pref_index(capability, x)))
+                       break;
+               if (alreadysent & pref_codec)
+                       continue;
+               if (!(p->userprefs.bits & pref_codec))
+                       continue;
               if (pref_codec <= AST_FORMAT_MAX_AUDIO)
                       add_codec_to_sdp(p, pref_codec, 8000,
                                        &m_audio_next, &m_audio_left,
Now “allow sequence” has no meaning if translation_algorithm=loose.
This is a small issue. Don’t know the side effect of my changing.

By: J.R. (jrast) 2006-02-21 13:46:22.000-0600

Tom: I am puzzled by what you're doing.  The code you're substituting is already there, just a few lines below where you are.  If no userprefs are set, or if you use the additional_patch, the existing code should do exactly what you seem to be looking for.

By: tom (tom) 2006-02-21 18:34:54.000-0600

Yes, if no userprefs are set, the existing code should do exactly what I am looking for. And I still don't have time to try the additional_patch.

My changing affects codecs adding order. If admin config phone2 "allow=ualaw&ualaw&H261&H263", when phone2a calls phone2b,
if phone2a->A* invite:
m=audio 7078 RTP/AVP 0
a=rtpmap:0 PCMU/8000
m=video 7080 RTP/AVP 96 31
a=rtpmap:96 H263-1998/90000
a=rtpmap:31 H261/90000
Using original patch without additional_patch, A*->phone2b invite:
m=audio 70781 RTP/AVP 0
a=rtpmap:0 PCMU/8000
m=video 70802 RTP/AVP 31 96
a=rtpmap:31 H261/90000
a=rtpmap:96 H263-1998/90000
While my changing reserved all the codecs order in phone2a->A*. A*->phone2b invite:
a=rtpmap:0 PCMU/8000
m=video 70802 RTP/AVP 96 31
a=rtpmap:96 H263-1998/90000
a=rtpmap:31 H261/90000
I would like that my admin has a choice to select specified codecs but doesn't care about their config order. This is what I want. If the additional_patch also does it, it's good. So I can maintain the same code with the public and ignore my changing.

Now I am much more concerned about the callee's DTMF. This's a crital issue.

By: tom (tom) 2006-02-21 19:28:16.000-0600

jrast & jeds: jrast's additional patch fixed callee's DTMF problem. Thanks, jrast.

By: tom (tom) 2006-02-22 00:38:33.000-0600

Here is another issue with the dynamic codecs. Suppose PhoneA call PhoneB

phoneA->Asterisk invite:
m=video 7080 RTP/AVP 96
a=rtmpmap:96 H263-1998/9000

then Asterisk->phoneB invite:
m=video 67080 RTP/AVP 103
a=rtmpmap:103 H263-1998/9000

PhoneB->Asterisk 200OK:
m=video 7080 RTP/AVP 103
a=rtmpmap:103 H263-1998/9000

But Asterisk->PhoneA 200OK:
m=video 7080 RTP/AVP 103
a=rtmpmap:103 H263-1998/9000
Thus, both Asterisk and PhoneA have to be prepared to receive H263+ media at either payloadtype 96 or 103. But Actually Asterisk can't recongize payload type 103. Therefore, here it should answer with "a=rtmpmap:96 H263-1998/9000". The payload type should be the same as the payloadtype in the invite SDP from PhoneA to Asterisk.

The 103 is the index of H263+ in static_RTP_PT on rtp.c. This is a genel issue found in A* even without the patch. I report it as issue 0006568.

By: jeds (jeds) 2006-02-22 00:55:49.000-0600

I'm still not getting DTMF send to the callee's side. Am I maybe missing something? I've applied jrast's patch as well.

By: tom (tom) 2006-02-22 01:09:13.000-0600

Do u config dtmfmode=rfc2833?

By: tom (tom) 2006-02-23 20:22:36.000-0600

What's the routine from A* receives the first invite from Phone1, to A* sends invite to Phone2? Who has any idea, Could you give a brief function list? Thanks.

By: J.R. (jrast) 2006-02-23 21:17:49.000-0600

Jeds: DTMF is working for me too, both ways.  I am using DTMF mode RFC2833 also.  You need to set RFC2833 as the DTMF mode in the phones as well as in A*.

In RFC2833 a DTMF "tone" is sent as an RTP packet coded with the DTMF payload type (usually 101, but can be anything 96..127, as long as the value chosen doesn't conflict with another codec).  The payload types used by the phones don't have to match... each phone tells the other what it will use during the SDP (re)negotiation.  You'll see stuff like this:
   m=audio 5004 RTP/AVP 18 3 0 101
   a=rtpmap:18 G729/8000
   a=rtpmap:3 GSM/8000
   a=rtpmap:0 PCMU/8000
   a=rtpmap:101 telephone-event/8000
   a=fmtp:101 0-11
Note the 101 on the m= line and the corresponding a= line.  Also note the fmtp which shows here that your phone will use payload type 101 for DTMF events 0-11 (which are the digits 0-9, * and #).  If either of your phones are not sending this during the SDP (re)negotiation, that phone probably won't be sending DTMF events as RTP packets.

As well as the sending phone originating DTMF RTP packets, the receiving phone must also regenerate the DTMF when it gets the packets.  Many phones have config options for the duration and level of the tones they regenerate.  If you have such options, check they are suitably set... a tone duration of 250-350ms is ususally OK, with a pause duration of 100ms, and a level of -10dBm generally works, too.  If the SDP negotiation did look OK, it could be that one of your phones isn't regenerating the DTMF when it receives that DTMF RTP packet.

If your receiver is, in fact, a program or other device that is listening for DTMF, it will need to understand RFC2833 also.  If it is merely scanning the audio for the tones, you'll need something to convert the RTP packets into audio first.

By: J.R. (jrast) 2006-02-23 21:21:32.000-0600

What is needed to elevate the work done here for the latest codec-negotiation.diff and the additional_patch.diff to the status where they are considered for inclusion in A*?

They are certainly working for me, and have reduced the transcoding to only those situations where two phones don't share any common codecs.  I'd like to see these added to A*-current, and possibly also into A*-1.2.4 or a future A*-1.2.5.

By: Vladimir Klejch (kleo) 2006-02-28 15:49:30.000-0600

I have now compiled * 1.2.4 with bamby's patch asterisk124_codec_negotiation-20060202_2.diff.gz and  asterisk124-additional_patch_jr.diff  for my wrt54gs running openwrt, that is doing firewall and nat for my home network. I use SIP phones with g729a and VOIP gw by VOICE provider is CISCO VOIP gw with g729 too. On the WRT is only ulaw codec instaled, but with this patch i cann call and receive calls with g729 and other codecs which are on both devices, when WRT only forwards rtp packets without recoding.
I need more tests, use more voip peers a do smart voip routing with * on WRT. I think, that this patch is very usefull for forwarding voip gateways, not only for my WRT router.
I need too test fax send and receive with fax on PAP2.

By: J.R. (jrast) 2006-03-01 17:26:12.000-0600

I believe there may be a problem with A*'s handling of phone-initiated reinvites.  It doesn't look like these are working, now.

This is separate from the initial invites and RTP reinvites that happen during call setup -- these invites are being handled very well with these patches.

This issue is not with the initial codec negotiation and reinvites, but it happens once a call is established, if call conditions change.  It is possible, while a call is in progress, that a phone may wish to change codecs, for example, if the user starts sending a different type of data.  To signal this, the phone will send a new SIP INVITE message for this call often with just a single codec choice.  A* receives this in channels/chan_sip.c:10593 in the routine handle_request_invite() where there is this code:
   case AST_STATE_UP:
           /* Here we have reINVITE request - try to renegotiate codecs with */
           transmit_response_with_sdp(p, "200 OK", req, 1);
All this does is send a "200 OK" back to the phone sending the new INVITE.  At this stage, A* should then reevaluate the new codec(s), compare it to the other channel's list, and issue new reINVITEs on both channels in order to either cause the phoneA<->phoneB session to switch to a new codec, or possibly for A* to reinsert itself back in the RTP path in a transcoding mode as phoneA<->A*transcoding<->phoneB.  In effect, A* must now redo the codec evaluation that it did during initial call setup.  Thing is, this is not happening, at all.

All that happens at the moment is that the phone trying to initiate the codec switch gets the "200 OK" response, and then the call carries on unchanged with the existing RTP path.  If the phone REQUIRES the new codec in order for it to continue with the call, it's out of luck, and it will then have no choice but to end the call, which is what I am seeing for one device here.

I will review the code some more and try to offer a patch in due course, but if anyone else has time and wants to take a look at this, please feel free.  I suspect this lies somewhere in handle_request_invite() or maybe in process_sdp() -- there is code there that appears to be relevant: it looks at the bridged peer and queues a null frame in order to "/* Activate a re-invite */".

By: Elazar Rosenthal (elazarrosenthal) 2006-03-02 14:29:52.000-0600

after patching asterisk-1.2.4.tar.gz with asterisk124_codeac_negotiation-20060202_2.diff

I get the following error in the build:

cc  -pipe  -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3  -Iinclude -I../include -D_REENTRANT -D_GNU_SOURCE  -O6 -march=i686 -DZAPTEL_OPTIMIZATIONS         -fomit-frame-pointer  -Wno-missing-prototypes -Wno-missing-declarations -DZAPATA_PRI -DIAX_TRUNKING -DCRYPTO -fPIC    -c -o chan_alsa.o chan_alsa.c
chan_alsa.c:188: warning: initialization from incompatible pointer type
chan_alsa.c: In function `alsa_new':
chan_alsa.c:788: error: incompatible types in assignment
make[1]: *** [chan_alsa.o] Error 1
make[1]: Leaving directory `/work/home/elazar/a14/asterisk-1.2.4/channels'
make: *** [subdirs] Error 1

   784                 tmp->tech = &alsa_tech;
   785                 snprintf(tmp->name, sizeof(tmp->name), "ALSA/%s", indevname);
   786                 tmp->type = type;
   787                 tmp->fds[0] = readdev;
****788                 tmp->nativeformats = AST_FORMAT_SLINEAR;
   789                 tmp->readformat = AST_FORMAT_SLINEAR;
   790                 tmp->writeformat = AST_FORMAT_SLINEAR;
   791                 tmp->tech_pvt = p;

note that tmp->readformat  seems to be a struct.

By: Vladimir Klejch (kleo) 2006-03-03 05:26:41.000-0600

This is my patch to compile chan_alsa, but i not tested it, if it works with local soudcard.

--- asterisk/channels/chan_alsa.c       2006-01-21 01:33:29.535093169 +0100    
+++ /tmp/dpep.k1wBv2/asterisk/channels/chan_alsa.c      2006-01-21 03:04:57.0960
00879 +0100                                                                    
@@ -787,7 +787,7 @@                                                            
               snprintf(tmp->name, sizeof(tmp->name), "ALSA/%s", indevname);  
               tmp->type = type;                                              
               tmp->fds[0] = readdev;                                          
-               tmp->nativeformats = AST_FORMAT_SLINEAR;                        
+               ast_codec_pref_append_missing2(&tmp->nativeformats, AST_FORMAT_SLINEAR);                                                                        
               tmp->readformat = AST_FORMAT_SLINEAR;                          
               tmp->writeformat = AST_FORMAT_SLINEAR;                          
               tmp->tech_pvt = p;

By: J.R. (jrast) 2006-03-03 09:16:12.000-0600

Kleo, Elazarrosenthal: Using ast_codec_pref_set2() may be better here.

By: J.R. (jrast) 2006-03-03 09:31:31.000-0600

Folks, the following code for handle_request_invite() seems to address the phone-initiated reINVITE problem which I described in note 41867, above:
   case AST_STATE_UP:
          /* Here we have reINVITE request - try to renegotiate codecs */
                  struct sip_pvt *pp = ast_bridged_channel(p->owner)->tech_pvt;
                  memcpy(&pp->formats, &p->formats, sizeof(p->formats));
                  pp->usercapability = p->formats.bits;
                  if (p->rtp)
                  if (p->vrtp)
                  ast_queue_frame(p->owner, &ast_null_frame);
          transmit_response_with_sdp(p, "200 OK", req, 1);
(This is for A*-current, by the way.  Something similar is probably needed on A*-1.2.4; I haven't merged this into that version, yet.)

This code takes the new codec list from the phone's reINVITE and inserts it into the peer's formats and usercapability, then stops the existing RTP and queues a null frame to cause renegotiation of the RTP session.

I am not totally thrilled with this code as we're now digging into the peer's pvt structure which is something that doesn't happen anywhere else.  And, I'm not sure we should be overriding the peer's usercapability, either.  But it seems this is required to address the problem.  If anyone has any better idea of how to accomplish this, it would be good to hear it.

By: J.R. (jrast) 2006-03-03 11:00:47.000-0600

Folks, I have taken the liberty of producing a new version of the complete codec_negotiation-20060303.diff patch file which I have just uploaded.

This contains Bamby's original diffs and my additional_patch and the further fixes that have been offered in the last few weeks; the whole lot adjusted so that it patches cleanly on today's SVN trunk.

This does include the code I just offered in note 42001, even though I'm not sure that code is the correct solution for that problem.  However, by including it in the .diff, more folk will be able to try it out and comment.

I do not yet have an updated version for 1.2.4, and probably won't have time to get to that for the time being.  I have other work that needs attention.

By: Denis Smirnov (mithraen) 2006-03-19 07:16:14.000-0600

4825.codec.negotiation.2006-03-19.patch -- updated to trunk with some my small API changes.

By: tom (tom) 2006-03-21 02:08:46.000-0600

Is codec_negotiation-20060303.diff for 1.2.5?

By: Paul Cadach (pcadach) 2006-03-23 10:23:02.000-0600

The patch (at least 4825.codec.negotiation.2006-03-19.patch) is not clear for me. Please, contact me at IRC to discuss some places.

By: Olle Johansson (oej) 2006-03-23 11:18:18.000-0600

Everyone that has uploaded changes to the patch needs to confirm that they have a disclaimer on file with Digium. Thanks.

By: Andriy I Pylypenko (bamby) 2006-04-04 11:07:25

Thanks to everyone who has sent fixes and reports. I've done my best to cope with the problems you mentioned but unfortunately I had little time to test and fix everything. I've made new version of patch for asterisk-1.2.6. The patch for trunk will be shortly.

The main change is that I've splitted video and audio codecs in ast_codec_pref structure so to be able to deal with each flavor of codecs separately.

The patch is available from my page. Unfortunately the old URL is no longer valid and now you can access it here:


By: E. Versaevel (erikje) 2006-04-05 04:07:01

Is there any way to tell if this actualy works? i've applied the patch from the external site to my 1.2.6 test asterisk and set the option in asterisk.conf to loose, however it still starts transcoding?

Peer 1 (alaw,g729) calls Peer 2 (g729) still 1 leg with alaw, 1 leg with g729

I'd be happy to test as i'm currently transcoding the hell out of my asterisk box :)

Currently i'm using * as softswtich to distribute calls from and to carriers, let's say:

CarrierA (g711, g729) --> Customer A (g729) Starts transcoding
Customer A (g729) --> CarrierA (g729) No transcoding (different peer with only g729)
CarrierA (g711, g729) --> Customer B (g711) no transcoding
Customer B (g711)  --> CarrierA (g711, g729) no transcoding

So i'm currently transcoding all inbound calls for Customer A which is not the best thing to do, * should switch to G729 at the carrier side

By: Andriy I Pylypenko (bamby) 2006-04-05 06:04:11

erikje: I see the problem. I have modified the patch to behave in loose mode in the following way:

UA1 -> A*: INVITE ALAW, G729
A* -> UA2: INVITE ALAW, G729, A, B, ...
UA2 -> A*: OK G729
A* -> UA1: OK G729 (was "OK ALAW, G729" without this change)

Please try the new version of the patch.

By: E. Versaevel (erikje) 2006-04-05 06:31:37

I will do so right now :)


Seems to work ok, i'll put it in production tonight. I only get some "Asked to write while native format" messages on the console

By: Andriy I Pylypenko (bamby) 2006-04-05 10:56:52

I'm uploading new version of patch against trunk. The patch contains changes that has been made earlier to patch against asterisk 1.2.6.

By: E. Versaevel (erikje) 2006-04-06 06:05:42

Bambi, i ran into a limitation of our carrier, they allways want g711 in the 200 OK otherwise they hangup imidiately, so what we should/could do is:

UA1 ->  A* : INVITE ALAW, G729
A*  -> UA2 : INVITE ALAW, G729, A, B, ...
UA2 ->  A* : OK G729
A*  -> UA1 : OK G729, ALAW (was "OK G729" without this change, however since ALAW is allso supported by * it should only change the preference I think?)

as our carrier reinvites us later with G729

Also, does this patch keep the allowed codec in the peer? (so don't send ALAW if its not in the allowd codec of the peer)

By: Andriy I Pylypenko (bamby) 2006-04-06 07:37:36

erikje: I was considering such behavior yesterday but only today I have found the way to do this correctly. Now incoming channel reorders its codec list according to the peer's response. This behavior no more depends on the translation_algoritm option.

Please check the new patch against the 1.2.6.

By: E. Versaevel (erikje) 2006-04-06 07:41:27

i'll give it another go tonight :)

Just a quick question, what happens if we set the outbound codec using ${SIP_CODEC} ? For some fax devices i need to force G711 both in & outbound

By: E. Versaevel (erikje) 2006-04-06 15:41:57

Bamby, this seems to work up until the point we recieve a reinvite from the other party, then asterisk responds with the original codec order, instead of the order derived from the other peers response.

so now it is:

UA1 -> A* : INVITE ALAW, G729
A* -> UA2 : INVITE ALAW, G729, A, B, ...
UA2 -> A* : OK G729
A* -> UA1 : OK G729, ALAW

so far so good, but then our carrier want to change the IP for the RTP stream so they send a reinvite:

A* -> UA1 : OK ALAW, G729

And * starts transcoding between UA1 and UA2 again :(

By: Andriy I Pylypenko (bamby) 2006-04-07 10:29:49

erikje: Two things:
1. In the case you've showed it isn't clear how the asterisk should act in response to the reINVITE. It can enforce g729 to keep the asterisk from transcoding. But if reINVITE was caused by the fax detection the asterisk is to reinvite the other UA to switch to G711 or simply respond 'OK G711, ...' if the application similar to RxFax is used. It's unclear for me now how to gather all the information required to make the correct decision.
2. I cannot reproduce this using the latest patch. I get 'OK G729, ALAW' in response to reINVITE. The behavior from your example I see in the FreeBSD port of asterisk - it has an additional patch that forces codecs to be read from reINVITE request into channel's nativeformats/formats and as the side effect this enables normal faxing using the RxFax application :-)

By: E. Versaevel (erikje) 2006-04-07 15:47:35

I'm not using any bsd port, nor fax detection :) I do see the problem, in my case i think G729 ALAW should be the correct order. I'll try again tomorrow and post the coresponging ngrep output

By: E. Versaevel (erikje) 2006-04-10 05:57:09

Bamby, i've tested again, same result, OK ALAW,G729 on the reinvite, please see the trace.txt file attached

By: Andriy I Pylypenko (bamby) 2006-04-10 08:12:21

erikje: I'm still unable to reproduce the issue. Can I ask you a few questions?
1. Are you using the asterisk126_codec_negotiation-20060406.diff.gz?
2. What the settings do you have for the 'canreinvite', 'allow' and 'disallow' options?
3. Do you have some other important peculiarities in you config?

By: E. Versaevel (erikje) 2006-04-10 08:21:22

1: Yes
3: no (translation_algorithm = loose)





call comes in on in.from.carrier

By: Andriy I Pylypenko (bamby) 2006-04-10 11:16:28

Unfortunately I'm unable to repeat the problem so I'm showing my setup. I hope it might help:






exten => _X.,1,Dial(SIP/${EXTEN})

I've got no g729 codec so I'm using ALAW and ULAW codecs for tests. The carrier calls 801 with 'INVITE PCMU, PCMA'. 801 responds with 'OK PCMA'. Then carrier reINVITEs with 'INVITE PCMU, PCMA' againg and Asterisk responds 'OK PCMA, PCMU'.

By: E. Versaevel (erikje) 2006-04-11 06:14:53

bamby, how about creating a version with some verbose debug information? That would definitly help locating this problem

By: E. Versaevel (erikje) 2006-04-13 08:02:34

Bambi, do you have a phone capable of G729? if so i could give you a g729 module for testing.

By: mihai (mihai) 2006-04-26 14:37:07


I am trying to access your repository at http://www.portaone.com/~bamby/public, but it redirects to the portaone main page.... anyway, is there a patch for 1.2.7[.1] version of asterisk? I'm currently using 1.2.4 and I'm running into some DTMF forwarding issues. I was wondering if the probelm is still there in

Thanks a bunch,

By: Vladimir Klejch (kleo) 2006-04-26 17:39:31

mihai: the correct url is http://unofficial.portaone.com/~bamby/public
an there is a file  asterisk127_codec_negotiation-20060419.diff.gz


By: mihai (mihai) 2006-04-27 09:35:46

Kleo: thanks

The patch applied OK, but I get an error at compilation:

gcc  -pipe  -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3  -Iinclude -I../include -D_REENTRANT -D_GNU_SOURCE  -O6 -march=i686 -DZAPTEL_OPTIMIZATIONS         -fomit-frame-pointer  -Wno-missing-prototypes -Wno-missing-declarations -DZAPATA_PRI -DIAX_TRUNKING -DCRYPTO -fPIC    -c -o chan_phone.o chan_phone.c
chan_phone.c: In function ‘phone_request’:
chan_phone.c:1186: error: ‘struct ast_codec_pref’ has no member named ‘bits’
make[1]: *** [chan_phone.o] Error 1


By: Russell Bryant (russell) 2006-04-30 09:54:04

I apologize that this issue has been sitting here for so long without review.  We recently started having weekly developer conference calls, which have proven very useful for discussing the larger scale changes, such as this.

Would you be able to make it to one of these calls?  I would be happy to put it on the agenda for discussion this week if you can make it.  It will be Tuesday, at 10 AM CDT (GMT -5).

Let me know what you think.  Thanks!

By: Andriy I Pylypenko (bamby) 2006-05-05 03:29:39

mihai: Thank you for your report. You can find new patch at http://unofficial.portaone.com/~bamby/public/

By: Serge Vecher (serge-v) 2006-05-05 09:00:07

bamby: can you please produce an updated patch for trunk. I will delete all the old patches then.

Also, let's see if we can have other people test the patch and _report_ successful results here in the BT to improve chances of this getting in.


By: Denis Smirnov (mithraen) 2006-05-05 09:02:06

Please, see to 6725, it can be used for simpler integration of this patch.

By: Andrey S Pankov (casper) 2006-05-06 11:04:09

vechers: this is not a trivial work to update the patch for trunk.
And I still see issues with ASTERISK-6548 (I'll comment them there).

By: Andriy I Pylypenko (bamby) 2006-05-11 07:47:18

I'm uploading the fresh patch agains trunk (rev 26876).

By: Serge Vecher (serge-v) 2006-05-11 09:23:36

bamby: thanks for you hard work and sticking with this one...

russell: does this patch needs it's own branch?

By: Ovidiu Sas (ovi) 2006-05-21 17:58:12


I'm running asterisk with this patch.
It seems to be pretty stable ... but I noticed this weird behaviour while doing some codec negotiation.  Here's the scenario:

I have a SIP client (Linksys/SPA3000) connected to asterisk (no native 729 codec module) placing a call to my VoIP service provider:

Linksys/SPA3000                asterisk             VoIP service provider
      |                          |                          |
      |----------INVITE--------->|                          |
m=audio 16468 RTP/AVP 0 2 4 8 18 96 97 98 100 101            |
a=rtpmap:0 PCMU/8000              |                          |
a=rtpmap:2 G726-32/8000           |                          |
a=rtpmap:4 G723/8000              |                          |
a=rtpmap:8 PCMA/8000              |                          |
a=rtpmap:18 G729a/8000            |                          |
a=rtpmap:96 G726-40/8000          |                          |
a=rtpmap:97 G726-24/8000          |                          |
a=rtpmap:98 G726-16/8000          |                          |
a=rtpmap:100 NSE/8000             |                          |
a=fmtp:100 192-193                |                          |
a=rtpmap:101 telephone-event/8000 |                          |
a=fmtp:101 0-15                   |                          |
a=ptime:30                        |                          |
a=sendrecv                        |                          |
      |                          |---------INVITE---------->|
      |                          |m=audio 50186 RTP/AVP 0 18 101
      |                          |a=rtpmap:0 PCMU/8000      |
      |                          |a=rtpmap:18 G729/8000     |
      |                          |a=fmtp:18 annexb=no       |
      |                          |a=rtpmap:101 telephone-event/8000
      |                          |a=fmtp:101 0-16           |
      |                          |a=silenceSupp:off - - - - |
      |                          |                          |
      |                          |<---183 Session Progress--|
      |                          |m=audio 19078 RTP/AVP 18 101
      |                          |c=IN IP4 81.ZZ.ZZ.ZZ      |
      |                          |a=rtpmap:18 G729/8000     |
      |                          |a=fmtp:18 annexb=no       |
      |                          |a=rtpmap:101 telephone-event/8000
      |                          |a=fmtp:101 0-16           |
      |                          |a=direction:passive       |
      |                          |                          |
      |<---183 Session Progress--|                          |
      |m=audio 50278 RTP/AVP 0 18 101                       |
      |a=rtpmap:0 PCMU/8000      |                          |
      |a=rtpmap:18 G729/8000     |                          |
      |a=fmtp:18 annexb=no       |                          |
      |a=rtpmap:101 telephone-event/8000                    |
      |a=fmtp:101 0-16           |                          |
      |a=silenceSupp:off - - - - |                          |
      |                          |                          |

During the ringback, I have media (ringback is played back to the caller) but there are lot's of WARNINGS:

WARNING[1928]: translate.c:133 ast_translator_build_path: No translator path from alaw to gsm
WARNING[1928]: translate.c:133 ast_translator_build_path: No translator path from alaw to gsm
WARNING[1928]: translate.c:133 ast_translator_build_path: No translator path from gsm to alaw
WARNING[1928]: chan_sip.c:2546 sip_write: Asked to transmit frame type 4, while native formats is 256 (read/write = 4/4)

The weird thing is that alaw and gsm are not part of the negotiated codecs.  In fact, gsm is not even offered.
After the call goes in conversation, all the warnings are gone because the 200ok is affering _only_ the 729 codec.

      |                          |                          |
      |                          |<---------200 OK----------|
      |                          |m=audio 19078 RTP/AVP 18 101
      |                          |c=IN IP4 81.ZZ.ZZ.ZZ      |
      |                          |a=rtpmap:18 G729/8000     |
      |                          |a=fmtp:18 annexb=no       |
      |                          |a=rtpmap:101 telephone-event/8000
      |                          |a=fmtp:101 0-16           |
      |                          |a=direction:passive       |
      |                          |                          |
      |<---------200 OK----------|                          |
      |m=audio 50278 RTP/AVP 18 101                         |
      |a=rtpmap:18 G729/8000     |                          |
      |a=fmtp:18 annexb=no       |                          |
      |a=rtpmap:101 telephone-event/8000                    |
      |a=fmtp:101 0-16           |                          |
      |a=silenceSupp:off - - - - |                          |
      |                          |                          |

Here's the outgoing context for my VoIP provider:

Here's the context for my Linksys/SPA3000

In my sip.conf I have:
disallow=all                    ; First disallow all codecs                    
allow=ulaw                      ; Allow codecs in order of preference          
allow=g729                      ; Allow codecs in order of preference          

I will upload also the full log file.

By: Ovidiu Sas (ovi) 2006-05-21 18:02:24

Pls. see the astersik.log.gz file.

PS: to bad that my ascii pic got messed up.

By: Jorrit Kronjee (jorrit at infopact nl) 2006-05-22 08:36:20


I've been trying to debug the problem posted by my colleague 'erikje' a few notes back. What I've found is the following:

On the first SIP INVITE, the function ast_bridge_call() will be called. From your patch I can see you do most of the codec negogiation from there.

On the second SIP INVITE (e.g. reINVITE) the function handle_request_invite() is called. In that case, apparently, the formats member in the struct sip_pvt has then already been overwritten by the reinvite. This causes asterisk to use the preferred codec to be the one set by our peer again.
This behaviour can be removed, by adding the following line to add_sdp() in channels/chan_sip.c (and commenting out the other):

/* Prefer the codec we were requested to use, first, no matter what */
//pref_codec = ast_codec_pref_index_audio(capability, 0);
pref_codec = 0;

However, I'm not entirely sure what this might break. I'm also not sure why this piece of code is there in the first place. It seems very braindead compared to the codec negogiation that's done beforehand.

What do you think?

By: Elazar Rosenthal (elazarrosenthal) 2006-05-22 09:39:26

I have been testng with a patched version of
I noticed that with the patch in place asterisk does not seem to be passing  touchtones

I am getting:

May 19 15:31:17 NOTICE[3573]: rtp.c:565 ast_rtp_read: Unknown  RTP codec 101

In the log files.

I will start looking into this myself but just want to see if there are any pointers.

By: Elazar Rosenthal (elazarrosenthal) 2006-05-22 13:49:49

I have traced my tt problem to

the folloiwng code in rtp.c:

* Make a note of a RTP paymoad type that was seen in a SDP "m=" line. */
/* By default, use the well-known value for this type (although it may */
/* still be set to a different value by a subsequent "a=rtpmap:" line): */
void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt) {
        * Get only static payload types here
       if (pt < 0 || pt > MAX_RTP_STATIC_PT)
               return; /* non-static payload type */

       if (static_RTP_PT[pt].code != 0) {
               rtp->current_RTP_PT[pt] = static_RTP_PT[pt];

if I change
if (pt < 0 || pt > MAX_RTP_STATIC_PT)
back to
if (pt < 0 || pt > MAX_RTP_PT)
things work

the TT rtp events (101) are the only "codecs" in my stream outside the STATIC range

is thia fix ok?
is there a proper way to add the 101 to the codec list?


By: Andrey S Pankov (casper) 2006-05-23 20:50:08

> is there a proper way to add the 101 to the codec list?
The proper way is to have payload type be negotiated...
Lots of devices use for example 98 or 96 payload type for RFC2833 events.

By: Serge Vecher (serge-v) 2006-06-06 15:51:52

bamby, unfortunately, the latest patch does not apply to r32306 of trunk (hunks fail in multiple files). Can you please update your patch and I will try to help you test it. Thanks very much.

By: Andriy I Pylypenko (bamby) 2006-06-14 01:45:54

I've uploaded new patch against trunk (rev 34061).

By: Jorrit Kronjee (jorrit at infopact nl) 2006-06-19 08:43:56

In addition of this patch, I made a small patch which fixes a few problems we had with the above bugfix.

We had two problems:
- reinvites caused asterisk to overwrite the preferred codecs, causing transcoding.
- if UA1 (preferred codecs in SIP INVITE: G711a, G729) and UA2 (preferred codecs in SIP OK: G729, G711a) started a conversation, asterisk would start transcoding between G711a for UA1 and G729 for UA2.

What this patch does:
- try to find a non-transcoding path between UA1 and UA2.
- send a reinvite with only this one codec if necessary.

How it's activated:
- set 'evadetranscoding=yes' in the global SIP configuration.
- (optional) set a codecweight=<integer>' for SIP peers.

I made this patch for asterisk I know this is not the latest version, but that's the only version I could get the codec negotiation patch working for. The latest version of the codec negotiation patch, being codec_negotiation-20060614.diff, doesn't patch against either of the specified svn revisions.

Tell me what you guys think.

My patch and bamby's patch can also be downloaded from:

By: Olle Johansson (oej) 2006-06-20 01:54:13

jorrit: Thanks for contributing!

Please note:
* You need to confirm that you've sent a disclaimer (as according to the bug guidelines)
* Please don't add totally different patches to an existing bug report
* We never add new functions to the release code. The work in this issue is now
  taking place in a branch called "codecnegotation" that is based on svn trunk.

Modify your work for that branch and test it again, then open a separate issue report for your patch.
Looking forward to checking it, after it has been properly disclaimed. The bug guidelines are to
be found on the front page of the bug tracker.


By: Herve JOURDAIN (hjourdain) 2006-06-28 08:35:42

Bamby, it seems the patch for release 1.2.9 doesn't compile with
On line 1186 of chan_phone.c,there's:

formats->bits & ...

that needs to be replaced by:


By: Serge Vecher (serge-v) 2006-06-28 09:18:53

hjourdain: please do not ask questions in this bug report regarding backported patches. This issue is specifically marked 'trunk' so only trunk development questions are acceptable. Thank you.

By: Serge Vecher (serge-v) 2006-06-28 09:28:02

I am marking this bug as [post 1.4]. After 1.4 branch is forked in the near future, hopefully this can be considered for trunk right away.

By: J.R. (jrast) 2006-07-24 21:58:33

Hello everyone.  It's been a while since I've had time to review this.

Back in mid-Feb, in fact in note 0041330, I posted two minor patches, the second of which was to correct the IP addr and port presented to peers behind NAT when doing a SIP redirect.  Looks like I missed the port in part of the patch.

The patch, as it is now, looks like this:
@@ -4444,14 +4484,18 @@

       if (p->redirip.sin_addr.s_addr) {
               dest.sin_port = p->redirip.sin_port;
-               dest.sin_addr = p->redirip.sin_addr;
-               if (p->redircodecs)
-                       capability = p->redircodecs;
+               if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)
+                       dest.sin_addr = p->ourip;
+               else
+                       dest.sin_addr = p->redirip.sin_addr;
+                if (ast_codec_pref_bits(&p->redircodecs)) {
+                        /* We are to get all compatible with redircodecs codecs */
+                       capability = &p->redircodecs;
+                }
       } else {
               dest.sin_addr = p->ourip;
               dest.sin_port = sin.sin_port;
       /* Determine video destination */
       if (p->vrtp) {
               if (p->vredirip.sin_addr.s_addr) {

But, in fact, it should be this:
@@ -4444,14 +4484,21 @@

       if (p->redirip.sin_addr.s_addr) {
-               dest.sin_port = p->redirip.sin_port;
-               dest.sin_addr = p->redirip.sin_addr;
-               if (p->redircodecs)
-                       capability = p->redircodecs;
+               if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) {
+                       dest.sin_port = sin.sin_port;
+                       dest.sin_addr = p->ourip;
+               }
+               else {
+                       dest.sin_port = p->redirip.sin_port;
+                       dest.sin_addr = p->redirip.sin_addr;
+               }
+               if (ast_codec_pref_bits(&p->redircodecs)) {
+                       /* We are to get all compatible with redircodecs codecs */
+                       capability = &p->redircodecs;
+               }
       } else {
               dest.sin_addr = p->ourip;
               dest.sin_port = sin.sin_port;
       /* Determine video destination */
       if (p->vrtp) {
               if (p->vredirip.sin_addr.s_addr) {
Please could this correction be substituted in the larger codec-nego patch.  Thanks.

By: Paul Cadach (pcadach) 2006-08-21 13:55:41

Is any updates for attached patches available?

By: chankm (chankm) 2006-09-12 03:44:33

sip1 (caller) <--> Asterisk <--> sip2 (callee)

sip1 supports only g729 and g711
sip2 supports only g711

In sip.conf

allow = g729
allow = g711

allow = g711

sip1 could not talk to sip2 because sip1's preferred codec is g729 while
sip2 preferred codec is g711.

In order to solve this problem, I have made a slight modification to the
sip_new(..) function in chan_sip.c to prevent Asterisk from selecting a
preferred codec. In sip.conf, canreinvite has to be configured to "yes" for both sip1 and sip2.

sip1 was able to talk to sip2 after the patch and sip.conf is used.

The patch file "codecnegotiationPatch" for chan_sip.c is attached. I used the the lastest chan_sip.c from svn trunk when creating the patch.
The patch also works for situations where a multi-codec phone wants to talk to another multi-codec phone.

Would this slight modification be breaking any other part of the codes ?

By: Andriy I Pylypenko (bamby) 2006-09-12 04:37:32

chankm: Please try the patch from this issue (backported versions are available at http://unofficial.portaone.com/~bamby/public/)
This patch was designed to handle situations similar to yours. Hope this would help.

By: chankm (chankm) 2006-09-12 07:57:25

hi bamby,

I am currently using Asterisk- from bristuff-0.3.0-PRE-1q.

When I patched asterisk129_codec_negotiation-20060629.diff onto
Asterisk-, there were a number of Hunk failures.

May I know if there is a patch for Asterisk- from bristuff-0.3.0-PRE-1q ?

Thank you.

By: Andriy I Pylypenko (bamby) 2006-09-12 08:06:27

chankm: asterisk129_codec_negotiation-2006062.diff appies cleanly on clean asterisk-

By: Denis Smirnov (mithraen) 2006-09-12 10:34:27

Can you create this patch for last trunk?

By: chankm (chankm) 2006-09-12 20:44:28

hi bamby,

I tried asterisk129_codec_negotiation-20060629.diff patch for the following scenario :

sip1 (caller) <--> Asterisk <--> sip2 (callee)



sip1 supported codecs are g729 and ulaw
sip2 supported codec is g729

sip1 could not connect to sip2. sip2 returns a "415 Unsupported Media Type".
From the SIP logs, Asterisk sent INVITE message with codecs = ulaw, gsm, alaw
to sip2. That is the reason why sip2 responded with a 415 message.

I would think that sip1 should be able to connect to sip2 since both support g729. Can you help me on this ?


By: wapz (wapz) 2006-09-28 09:28:17

Will this patch make it into 1.4? I've seen nothing yet so far in 1.4Beta2. It still negociates endpoints separately from each other, not evading any transcoding.

By: Serge Vecher (serge-v) 2006-09-28 09:55:10

I think this needs an update to trunk after all the changes.

By: Jorrit Kronjee (jorrit at infopact nl) 2006-09-29 02:30:17

I'm sorry, but I probably won't have the time to make the evade transcoding patch , which was built on top of the codec negotiation patch from bamby, available for asterisk 1.4.

By: wapz (wapz) 2006-09-29 05:49:26

jorrit / others,

with 1.4 codec decisions seems to be solid between asterisk and the ua, but no logic to get asterisk to get codecs working at both sides. from my understanding that should make it very easy to make a patch that makes sure that two ua's at both sides not using the same codec is impossible, which is different from 1.2+. what is available for 1.4 now, and what are the possible options?


By: Jorrit Kronjee (jorrit at infopact nl) 2006-09-29 05:59:20


I'm not saying it's impossible, but a lot has changed in codec negotiation for 1.4. What I did for is quite simple:

1. Get the codec list from UA1
2. Get the codec list from UA2
3. See if they use a similar codec. If so, send a REINVITE to both parties with only this codec in the list. This will enforce the codec, because otherwise the UA might still be able to pick another codec, as long as it is in the list.
4. Ta da, no more transcoding!

By: wapz (wapz) 2006-09-29 06:10:36


that's one way to do it, but it does cause you to connect a call before knowing if it can actually connect. long-live the startup costs of pstn-connected networks.

a call setup that refuses a call from asterisk if the codec is not available on both sides would be a much cleaner solution. just drop the call setup when no exact codecs are available without hard-coding the codec options in the sip.conf per context. otherwise, just make sure to only confirm the codecs that are offered by both ends.

it could be such an easy setting by putting this in asterisk with a switch in sip.conf without affecting any other normal users of asterisk. i just hope something like that will be possible anytime soon, because that would be a really, really useful :)

By: Olle Johansson (oej) 2006-10-31 05:13:21.000-0600

jorrit: Do you have a disclaimer on file?
Bamby: Do you have an update for svn trunk?

We need to evaluate this in comparision with other proposals and changes that is in the works. I can put this code in a branch to keep it in synch meanwhile.

By: Jorrit Kronjee (jorrit at infopact nl) 2006-10-31 05:16:59.000-0600


I have a disclaimer on file.

By: Jan Hazenberg (jenus) 2006-11-22 08:49:27.000-0600

Does anybody know if this patch is available for asterisk 1.2.13. Or is this patch already included in this version?

By: Serge Vecher (serge-v) 2006-11-29 08:53:42.000-0600

jenus: no -- these patches are for trunk only and not for release branches (1.2.x and 1.4.x)

By: pj (pj) 2006-11-29 09:07:41.000-0600

can this patch be included in svn trunk for general evaluation or should we still wait for some corrections/improvements?

By: Vladimir Klejch (kleo) 2006-11-29 09:23:56.000-0600

jenus:  for 1.2.13 try patch from bamby:



By: wapz (wapz) 2006-11-29 09:25:13.000-0600

This feature should definitely be in 1.4, since not having this is by far the biggest drawback in Asterisk currently in the perspective of many people I've spoken with. Nothing really happened with this for the last couple of months, which is a real shame. If it is a feature you can disable anyway, what would be the reason not implementing it in 1.4 yet?

Maybe we'll have to pirate the release codes and release patches for normal releases.

update: ah, somebody is already doing this. excellent stuff.

By: Jan Hazenberg (jenus) 2006-11-29 15:35:53.000-0600

Thnx for the link kleo, the patch applied perfectly. I'm going to do some testing tomorrow.

By: Serge Vecher (serge-v) 2006-11-30 11:28:46.000-0600

well, we are still waiting for bamby to post the trunk patch here ...

By: Jan Hazenberg (jenus) 2006-12-01 08:27:52.000-0600

It seems to work ok, if one endpoint only supports one codec that codec will be used. If a supported codec isen't found on both sides the call is dropped with a sip 503 Service Unavailable. I still have some issues with the gateway i'm using but i'm hoping to fix that this weekend. For some reason it doesen't accept some codecs asterisk is presenting (i tested with G723), but it looks like asterisk is doing what is supposed to do :) I will get back here after the weekend with some more test results.

By: Serge Vecher (serge-v) 2006-12-01 11:39:02.000-0600

which just reminded me of something: if anybody else is willing to update bamby's work to trunk, that would be great and appreciated. Thanks!

By: Jan Hazenberg (jenus) 2006-12-15 04:38:49.000-0600

I have done some testing this week and it seems to work, my setup is:

[sip client]-------------[Asterisk]-----------[Cisco gateway]

On asterisk i have allow=all and the gateway is presenting all supported codecs.

I now can force the codec from the client side but i have to present only one codec from the client side. If i present for example G729 and Alaw then the outbound calls from the sip client work in g729, but the inbound call comming from   the gateway still uses Alaw since this codec has a higher prio on the gateway.

Is there someting i can change in behaviour? I would be nice if i can force asterisk to always try to use the codec the client is presenting instead of the codec that the gateway is presenting (with inbound calls comming from the gateway). I was reading trough the code of the chan_sip.c but i can't figure out  how and if this is possible. Does anybody here know if this is someting that can be changed?

I found one issue with this patch, the REGISTER channels in the show sip channels output seems to stay up and don't dissapear. Example:

Peer             User/ANR    Call ID      Seq (Tx/Rx)  Form  Hold     Last Message    (None)      60F01035-8A  00101/00478  unkn  No       Rx: REGISTER    (None)      EEA410BC-8A  00101/00373  unkn  No       Rx: REGISTER

Without the patch this isen't the case and then the channels disapear after a few minutes. With the patch these channes stay up, i unplugged my ethernet connection on the test box for one night and the channels were still there the next morning. To remove the channels i have to do a full restart of asterisk (a reload doesen't solve this). Does anybody here have the same problem? I'm currenly using asterisk 1.2.13 with the patch from bamby but it applied perfect.


By: Jan Hazenberg (jenus) 2007-01-04 09:10:20.000-0600

I have the patch working fine now with asterisk 1.2.14 , the hanging register channels issue seems to be gone.

I'm now testing with the new 1.4 release, since 1.4 supports T.38 passthrough and 1.2.14 doesen't. Is there already a working patch for the latest 1.4 release or should the old patch be modified?


By: Serge Vecher (serge-v) 2007-01-04 09:37:48.000-0600

jenus: how many times do I need to repeat myself? This new feature is not going into any of the release branches. Do you want a T.38-redux? Keep being stubborn and we will be discussing backports of the patch for 1.8. If you want to help, please update/forward-port the working patch to the current trunk or support somebody who can do that for you. If you are not able to do that, please do not post to the bug-tracker. Thank you.

By: J.R. (jrast) 2007-01-24 17:12:38.000-0600

Folks, there appear to be two problems with the code below in add_sdp().  This code is supposed to determine the proper peer IP address for use during SIP reinvites.

From A* 1.2.13, chan_sip.c, line 4545:
       if (p->redirip.sin_addr.s_addr) {
               dest.sin_port = p->redirip.sin_port;
               if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) {
                       dest.sin_port = sin.sin_port;
                       dest.sin_addr = p->ourip;
               } else {
                       dest.sin_port = p->redirip.sin_port;
                       dest.sin_addr = p->redirip.sin_addr;
               if (ast_codec_pref_bits(&p->redircodecs)) {
                       /* We are to get all compatible with redircodecs codecs */
                       capability = &p->redircodecs;
       } else {
               dest.sin_addr = p->ourip;
               dest.sin_port = sin.sin_port;
       /* Determine video destination */
       if (p->vrtp) {
               if (p->vredirip.sin_addr.s_addr) {
                       vdest.sin_port = p->vredirip.sin_port;
                       vdest.sin_addr = p->vredirip.sin_addr;
               } else {
                       vdest.sin_addr = p->ourip;
                       vdest.sin_port = vsin.sin_port;
The first problem is that the code for the audio and the code for the video are different.  They should be symmetrical.  This may be my fault; I suggested a patch to this code earlier in this Issue, way back in Feb 2006.  I suggested a change to the audio and the same change should have also been made for the video but this was overlooked.  This needs to be fixed.

The second problem is that the code doesn't always work as it should.  When one or both parties have the NAT flag set, or when canreinvite=no, reinvites are disabled and the code works.  When both parties are on the same net (either both inside, or both outside a firewall) reinvites are done and the code also works properly.

However, if the A* server is on a multi-homed machine with one party internal and the other party external and reinvites are enabled (using nat=no and canreinvite=yes), it fails.  This is because A* is sending the internal (non-routable) IP to the external party when it sends the reinvites.  The result is one-way audio.

My goal is for this to work in all cases, both with nat/canreinvite restrictions set but also with "nat=no" and "canreinvite=yes" unrestricted for all parties.  Such settings should work, but it turns out that these are also useful to allow support of mobile handsets (e.g., WiFi handsets or laptops with softphones) which, at different times, might register either inside or outside the firewall.

I believe the following code should replace what is there:
       if (ast_apply_ha(localaddr, &p->sa) && !ast_apply_ha(localaddr, &p->redirip))
               ast_set_flag(p, SIP_NAT_ROUTE);

       if (p->redirip.sin_addr.s_addr && !(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) {
               dest.sin_port = p->redirip.sin_port;
               dest.sin_addr = p->redirip.sin_addr;
               if (ast_codec_pref_bits(&p->redircodecs)) {
                       /* We are to get all compatible with redircodecs codecs */
                       capability = &p->redircodecs;
       } else {  
               dest.sin_addr = p->ourip;
               dest.sin_port = sin.sin_port;
       /* Determine video destination */
       if (p->vrtp) {
               if (p->vredirip.sin_addr.s_addr && !(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) {
                       vdest.sin_port = p->vredirip.sin_port;
                       vdest.sin_addr = p->vredirip.sin_addr;
               } else {
                       vdest.sin_addr = p->ourip;
                       vdest.sin_port = vsin.sin_port;
For folk interested in testing, here is a diff to make it easier to apply:
--- chan_sip.oc Wed Jan 24 12:48:29 2007
+++ chan_sip.c  Wed Jan 24 17:43:56 2007
@@ -4542,15 +4542,12 @@
       if (p->vrtp)
               ast_rtp_get_us(p->vrtp, &vsin);

-       if (p->redirip.sin_addr.s_addr) {
+       if (ast_apply_ha(localaddr, &p->sa) && !ast_apply_ha(localaddr, &p->redirip))
+               ast_set_flag(p, SIP_NAT_ROUTE);
+       if (p->redirip.sin_addr.s_addr && !(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) {
               dest.sin_port = p->redirip.sin_port;
-               if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) {
-                       dest.sin_port = sin.sin_port;
-                       dest.sin_addr = p->ourip;
-               } else {
-                       dest.sin_port = p->redirip.sin_port;
-                       dest.sin_addr = p->redirip.sin_addr;
-               }
+               dest.sin_addr = p->redirip.sin_addr;
                if (ast_codec_pref_bits(&p->redircodecs)) {
                        /* We are to get all compatible with redircodecs codecs */
                       capability = &p->redircodecs;
@@ -4561,7 +4558,7 @@
       /* Determine video destination */
       if (p->vrtp) {
-               if (p->vredirip.sin_addr.s_addr) {
+               if (p->vredirip.sin_addr.s_addr && !(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) {
                       vdest.sin_port = p->vredirip.sin_port;
                       vdest.sin_addr = p->vredirip.sin_addr;
               } else {
I'd really appreciate some feedback from others on this suggestion and I'd also appreciate if others could test and verify this works and doesn't break things for them, as I am unable to test too many different configurations at the moment.  Thanks.

By: Olle Johansson (oej) 2007-02-24 03:26:36.000-0600

Please check the "videocaps" branch where we change a lot of negotiation for video, which will be ported over to audio too.

By: Joel Jacobson (joelj) 2007-04-21 11:26:26

Hey guys,

I think I came up with a good/stable/simple 4 lines patch, which will put an end to your headache.

Add this to the proper place in channels/chan_sip.c:
pbx_builtin_setvar_helper(tmp, "SIPCODEC", ast_getformatname(fmt));

If you are using OOH323c, add this to asterisk-addons-1.4.0/asterisk-ooh323c/src/chan_h323.c:
pbx_builtin_setvar_helper(ch, "_CALLER_H323CODEC", ast_getformatname(fmt));

Create one SIP peer for each codec:

Route the calls via a little AGI script:
%input = $AGI->ReadParse();
$EXTEN = $AGI->get_variable('EXTEN');
my $codec = $AGI->get_variable('CALLER_H323CODEC') || $AGI->get_variable('SIPCODEC');
$AGI->exec('Dial','SIP/' . $number . '@' . $peer . $codec);

OK, it's a hack, but it does the trick..

By: pj (pj) 2007-05-15 15:21:56

can anybody update patch for current trunk?
please don't let this work death like happened with
0003346: [patch] PREFERRED_CODEC - codec preference override
current state of codecs negotiation in asterisk is very limited and there is currently no way to minimize unneeded transcoding, this is imho, one of the major weakness of all asterisk project;(

By: Rudy K. (cyberglobe) 2007-06-13 11:36:35

Does anyone have a working 1.2.18 patch willing to produce a diff file?  I would like to try this patch to see if I can eliminate transcoding altogether.

I am in dire need of proper codec selection system since Asterisk is currently not properly negotiating connections with a mixed phone setup (1 phone with G729, another with g711/g729 another with g711, etc)  

Atleast 2 of the 3 phones can talk without having RTP going through Asterisk.  but for the G711 and G729 phone, that would only be transcoded.

Did Bamby fall of the face of this planet?  Last time I saw him post is:
09-12-06 08:06   bamby   Note Added: 0051586

Did anyone go ahead and ported the 1.2.12 fixes to 1.2.18 version yet?  If I get no reply by next week, I will "TRY" to spend some time updating the DIFF file with the necessary fixes needed and repost it here hopefully it would get placed into the source code for testing after that.

By: Michael van der Kolff (mvdk) 2007-11-10 00:41:22.000-0600

Well, I'm happy to try to update this to trunk, but does this patch actually have any chance of being integrated?  Else the original maintainer (or someone connected to him) is still maintaining the patchset at b2bua.org.



By: Ovidiu Sas (ovi) 2007-11-27 13:19:04.000-0600

The patch seems to be actively maintained by sippy:

It is available for both 1.2 and 1.4 version (check the Download section).

By: Jason Parker (jparker) 2008-02-14 17:30:48.000-0600

The development team has given the area of codec negotiation a lot of thought.  It was actually a major item of discussion at the last developer conference.  We have a lot of ideas in place, but the implementation that we would like to proceed with is different than what has been proposed here.  While this issue has provided a nice patch that has been useful to people, I am going to close it out as we will be proceeding with a different approach.

We are fully aware of the issues that need to be addressed.  There is definitely a major lack in the entire area of codec negotiation - both pre-call, as well as changing codecs mid-call.

This is something we would like to work on in the not-too-distant future - we want to give codec negotiation (audio and video) the overhaul it needs.  While we will be taking a different approach, the information that has been presented here has been quite valuable, and will continue to be valuable as we progress towards this goal.

By: Andriy I Pylypenko (bamby) 2015-03-10 10:16:31.482-0500


I want to return to the issue with the codec negotiation. The key component of the patch never reached the Asterisk code, so I'm re-submitting the patch. The idea was to pass the real codec list (which is now the ast_format_cap structure) from one channel to another so the other channel can make realistic assumptions about which codecs may and which may not be proposed on the second call leg. Another important information is what the most preferred codec is, in my previous patch this was the first codec in the list.

Asterisk code now uses an ao2 container for that list so the task now is simpler. However the container is a hash and does not allow to keep ordered lists, so I've changed options to the ao2_container_alloc_options() call so that the container has only one bucket instead of default 283 and so it works now like a simple list.

I'm attaching the asterisk-11.13.0-codec-negotiation-20141006.diff.gz file. It however works ok with Asterisk 11.16.0 too.

By: Alisher (licedey) 2016-04-14 00:57:17.989-0500

Hi I tested the patch with Latest Asterisk 11.22.0 version. It works fine for audio codecs, but audio codec translation doesn't work for video calls that use H.264 video codec. Asterisk tries to translate from ulaw to H264 or from h264 to audio codec and throws the errors.