Controlling Codec Selection from Dialplan

I’m working on a project where I need to be able to limit the codec of an outgoing call via the dialplan. Specifically, I need to enable to disable h264 (video) on some calls, while allowing it on others. After doing some research I located Malcolm Davenport’s page on SIP Channel Variables here wiki.asterisk.org/wiki/display/ … +Variables and took a shot and using the SIP_CODEC options referred to. However, this did not appear to have any affect on the call being placed.

The scenario is that asterisk places a call (using a .call file in the /var/spool/asterisk/outgoing directory) and connects it to a music file being played. If the value of the “Video” variable being SET in the .call file is true then the resulting call should be ulaw|h264 if it is false the resulting call should be ulaw only.

The problem that I am having is that if the Video=false (as below) asterisk still sets up ulaw|h264. If I add limit the codec on in the device’s context in sip.conf using disallow=all allow=ulaw, then only ulaw is setup.

Any help that could be provided would be greatly appreciated. I believe that I’ve included all the relevant details, but if I’ve missed something please let me know, I would be more than happy to add additional details.

My config is as follows
Asterisk Version = 11.12.0

The content of the .call file being used

Channel: Local/100105@custom-dtmf-callback Set: Video=false Set: Data=003#1001*-1001-02-60 MaxRetries: 0 RetryTime: 10 WaitTime: 45 Context: custom-dtmf-calledwait Extension: s Priority: 1

From sip.conf

[general] disallow=all allow=ulaw allow=alaw allow=gsm allow=g722 allow=h264 allow=h263

From extensions.confg

[code][custom-dtmf-callback]
exten => _xxxxxx,1,NoOp(Calling the callback process with the DTMF string number)
same => n,Answer()
same => n,NoOp(This callback should be a Video Call: ${Video}
same => n,NoOp(Currently the outgoing codec is ${SIP_CODEC_OUTBOUND} . . . .)
same => n,GotoIf($[${Video} = true]?yesvid:novid)
same => n,Hangup()
same => n(startcallback),NoOp(Starting Callback)
same => n,Wait(${EXTEN:4})
same => n,Set(CDR(userfield)=Callback ${EXTEN:-6:-2} )
same => n,Dial(SIP/${EXTEN:-6:-2})
same => n,Hangup()
same => n(yesvid),Set(SIP_CODEC_OUTBOUND=ulaw&h264)
same => n,Set(SIP_CODEC_INBOUND=ulaw&h264)
same => n,Set(SIP_CODEC=ulaw&h264)
same => n,goto(startcallback)
same => n(novid),Set(SIP_CODEC_OUTBOUND=ulaw)
same => n,Set(SIP_CODEC_INBOUND=ulaw)
same => n,Set(SIP_CODEC=ulaw)
same => n,goto(startcallback)

[custom-dtmf-calledwait]
exten => s,1,NoOp(Called Device Back)
same => n,NoOp(Value of Video: ${Video}
same => n,NoOp(Currently the outgoing codec is ${SIP_CODEC_OUTBOUND} . . . .)
same => n,GotoIf($[${Video} = true]?yesvid:novid)
same => n,Hangup()
same => n(yesvid),Set(SIP_CODEC_OUTBOUND=ulaw&h264)
same => n,Set(SIP_CODEC_INBOUND=ulaw&h264)
same => n,Set(SIP_CODEC=ulaw&h264)
same => n,goto(playback)
same => n(novid),Set(SIP_CODEC_OUTBOUND=ulaw)
same => n,Set(SIP_CODEC_INBOUND=ulaw)
same => n,Set(SIP_CODEC=ulaw)
same => n,goto(playback)
same => n(playback),Background(custom/Ready_to_Go_Up_Higher)
same => n,Hangup()[/code]

Asterisk CLI output is:

-- Attempting call on Local/100105@custom-dtmf-callback for s@custom-dtmf-calledwait:1 (Retry 1) -- Executing [100105@custom-dtmf-callback:1] NoOp("Local/100105@custom-dtmf-callback-00000030;2", "Calling the callback process with the DTMF string number") in new stack -- Executing [100105@custom-dtmf-callback:2] Answer("Local/100105@custom-dtmf-callback-00000030;2", "") in new stack -- Executing [s@custom-dtmf-calledwait:1] NoOp("Local/100105@custom-dtmf-callback-00000030;1", "Called Device Back") in new stack -- Executing [s@custom-dtmf-calledwait:2] NoOp("Local/100105@custom-dtmf-callback-00000030;1", "Value of Video: false") in new stack -- Executing [s@custom-dtmf-calledwait:3] NoOp("Local/100105@custom-dtmf-callback-00000030;1", "Currently the outgoing codec is . . . .") in new stack -- Executing [s@custom-dtmf-calledwait:4] GotoIf("Local/100105@custom-dtmf-callback-00000030;1", "0?yesvid:novid") in new stack -- Goto (custom-dtmf-calledwait,s,10) -- Executing [s@custom-dtmf-calledwait:10] Set("Local/100105@custom-dtmf-callback-00000030;1", "SIP_CODEC_OUTBOUND=ulaw") in new stack -- Executing [s@custom-dtmf-calledwait:11] Set("Local/100105@custom-dtmf-callback-00000030;1", "SIP_CODEC_INBOUND=ulaw") in new stack -- Executing [s@custom-dtmf-calledwait:12] Set("Local/100105@custom-dtmf-callback-00000030;1", "SIP_CODEC=ulaw") in new stack -- Executing [s@custom-dtmf-calledwait:13] Goto("Local/100105@custom-dtmf-callback-00000030;1", "playback") in new stack -- Goto (custom-dtmf-calledwait,s,14) -- Executing [s@custom-dtmf-calledwait:14] BackGround("Local/100105@custom-dtmf-callback-00000030;1", "custom/Ready_to_Go_Up_Higher") in new stack -- <Local/100105@custom-dtmf-callback-00000030;1> Playing 'custom/Ready_to_Go_Up_Higher.slin' (language 'en') -- Executing [100105@custom-dtmf-callback:3] NoOp("Local/100105@custom-dtmf-callback-00000030;2", "This callback should be a Video Call: false") in new stack -- Executing [100105@custom-dtmf-callback:4] NoOp("Local/100105@custom-dtmf-callback-00000030;2", "Currently the outgoing codec is . . . .") in new stack -- Executing [100105@custom-dtmf-callback:5] GotoIf("Local/100105@custom-dtmf-callback-00000030;2", "0?yesvid:novid") in new stack -- Goto (custom-dtmf-callback,100105,16) -- Executing [100105@custom-dtmf-callback:16] Set("Local/100105@custom-dtmf-callback-00000030;2", "SIP_CODEC_OUTBOUND=ulaw") in new stack -- Executing [100105@custom-dtmf-callback:17] Set("Local/100105@custom-dtmf-callback-00000030;2", "SIP_CODEC_INBOUND=ulaw") in new stack -- Executing [100105@custom-dtmf-callback:18] Set("Local/100105@custom-dtmf-callback-00000030;2", "SIP_CODEC=ulaw") in new stack -- Executing [100105@custom-dtmf-callback:19] Goto("Local/100105@custom-dtmf-callback-00000030;2", "startcallback") in new stack -- Goto (custom-dtmf-callback,100105,7) -- Executing [100105@custom-dtmf-callback:7] NoOp("Local/100105@custom-dtmf-callback-00000030;2", "Starting Callback") in new stack -- Executing [100105@custom-dtmf-callback:8] Wait("Local/100105@custom-dtmf-callback-00000030;2", "05") in new stack -- Executing [100105@custom-dtmf-callback:9] Set("Local/100105@custom-dtmf-callback-00000030;2", "CDR(userfield)=Callback 1001 ") in new stack -- Executing [100105@custom-dtmf-callback:10] Dial("Local/100105@custom-dtmf-callback-00000030;2", "SIP/1001") in new stack == Using SIP VIDEO TOS bits 136 == Using SIP VIDEO CoS mark 6 == Using SIP RTP TOS bits 184 == Using SIP RTP CoS mark 5 -- Called SIP/1001 -- SIP/1001-00000093 is ringing -- SIP/1001-00000093 answered Local/100105@custom-dtmf-callback-00000030;2

I believe that I may have figured this out.

It appears that you set enable inheritance on the SIP_CODEC variable for it to work as expected. I tested with two underscores (enabling indefinite inheritance).

 same => n,Set(__SIP_CODEC=ulaw)

I will need to do more testing to determine if this actually completely solves my issue, but so far so good.

I’m still very interested in hearing any feedback on this.

Did some more in depth testing and find that this is working well when starting with a Video call ulaw + h264 and drop video while keeping only the audio ulaw codec.

New problem is, when starting with a ulaw only call and adding video using

 same => n,Set(SIP_CODEC=h264)

Asterisk CLI returns

[2014-09-22 21:12:07] NOTICE[1915][C-0000001d]: chan_sip.c:7099 try_suggested_sip_codec: Changing codec to 'h264' for this call because of ${SIP_CODEC} variable
[2014-09-22 21:12:07] NOTICE[1915][C-0000001d]: chan_sip.c:7104 try_suggested_sip_codec: Ignoring ${SIP_CODEC} variable because it is not shared by both ends.

because the use of SIP_CODEC replaces the existing codec with the specified codec. For a successful video call both ulaw and h264 codecs need to be present (in this case) and the SIP_CODEC family of variables do not allow for more than one codec to be specified.

Research indicates that this may have been fixed in an earlier Asterisk 11 release but I am not able to confirm this. It appears that this was resolved with bug 21976.

I have attempted specifying two codecs using several methods =ulaw,h264 =ulaw&h264 =ulaw|h264 etc. All attempts is an error indicating that the codec is not known.

[2014-09-22 21:20:21] NOTICE[5817][C-0000001e]: chan_sip.c:7106 try_suggested_sip_codec: Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): ulaw,h264

Any assistance that could be provided would be greatly appreciated.

[quote=“rollinsd”]
The scenario is that asterisk places a call (using a .call file in the /var/spool/asterisk/outgoing directory) and connects it to a music file being played. If the value of the “Video” variable being SET in the .call file is true then the resulting call should be ulaw|h264 if it is false the resulting call should be ulaw only.
[/code]

from what I know, it is not that easy to control the codec from the dialplan. I would try - should the remote server allow it - to create two trunks to the remote server, one with h264 enabled and the other one with ulaw only, and dial on the appropriate trunk