Asterisk local channels

Local channel

chan_local is a pseudo-channel. Use of this channel simply loops calls back into the dialplan in a different context. Useful for recursive routing; it is able to return to the dialplan after call completion.


Local/extension@context[/nj] (starting with Asterisk 1.6, backport available for 1.4)

Adding "/n" at the end of the string will make the Local channel not do a native transfer (the "n" stands for "n"o release) upon the remote end answering the line. This is an esoteric, but important feature if you expect the Local channel to handle calls exactly like a normal channel. If you do not have the "no release" feature set, then as soon as the destination (inside of the Local channel) answers the line, the variables and dial plan will revert back to that of the original call, and the Local channel will become a zombie and be removed from the active channels list. This is desirable in some circumstances, but can result in unexpected dialplan behavior if you are doing fancy things with variables in your call handling.

Adding "/nj" will apply the the generic jitterbuffer to the Local channel driver; this feature was introduced in Asterisk 1.6, with a backport being available for 1.4 (see link above on how to obtain it from svn). With this jitter buffer and a Local channel now also calls that aren't bridged but 'talk' to an Asterisk application can take advantage of de-jittering - provided the generic jitter buffer (not the older adaptive jitter buffer?) has been enabled in SIP (or MGCP or ...).


The Local channel construct can be used to establish dialling into any part of the dialplan.

Imagine you have a TE410P in your box. You want to do something for which you must use a Dial statement (for instance when dropping files in /var/spool/outgoing) but you do want to be able to use your dialplans least-cost-routes or other intelligent stuff. What you could do before we had chan_local was create a cross-link between two ports of the TE410P and then Dial out one port and in the other. This way you could control where the call was going.

Of course, this was a nasty hack, and to make it more sensible, chan_local was built.

The "Local" channel driver allows you to convert an arbitrary extension into a channel. It is used in a variety of places, including agents, etc.

Here are some examples (primarily using conferencing) where it might be useful:
  • Suppose you wanted to build a web GUI for building conferences... You could make your script ask for what number to call and use Local/number@context as the channel in your .call file, and set the conference as the extension to go to.
  • Imagine you had a conference going on and you wanted to be able to add someone in sales. You could use Local/salesexten@context as the channel to add to the conference, which would then ring everyone in sales.
  • Imagine you wanted to link two conferences together.
  • Imagine you wanted to add MusicOnHold to a conference.
  • You'd like to use .call files for automated dialling and still want to make sure that a CDR record = log entry gets created

This also allows us to hop to contexts like a GoSub routine; See examples below.


; here falls all incoming calls
exten => s,1,Answer
exten => s,2,Dial(local/200@internals,30,r)
exten => s,3,Playback(sorrynoanswer)
exten => s,4,Hangup

; here where our phones falls for default
exten => 200,1,Dial(sip/blah)
exten => 200,102,VoiceMail(${EXTEN}@default)

exten => 201,1,Dial(zap/1)
exten => 201,102,VoiceMail(${EXTEN}@default)

exten => _0.,1,Dial(Zap/g1/${EXTEN:1}) ; outgoing calls with 0+number

so that let me to call a local (internal) extension, without:
  • duplicate the dial & voicemail statements
  • don't letting them to dial out, since in internal context I have the possibility to dialout.

Using the local channel to play music on hold when already answered while waiting for a script that takes a while:


exten => s,1,Dial(local/s@somescript,60,m)


exten => s,1,Ringing
exten => s,n,System(' .. something which takes a lot of work ..')
exten => s,n,Answer()

One could create a special music on hold class saying 'please wait while we process your request'. Just remember that the caller may fall into the music on hold loop at any point.

In Manager API or in a call-file, a CDR will not be generated without using the local channel. At its simplest, use these examples to Dial:

For Manager API or in a call-file use the following to specify an outbound call. (the trailing '/n' is important):

Channel: local/PHONENUMBERTOCALL@outbound/n

And in extensions.conf:

exten => _1.,1,Dial(SIP/${EXTEN}@some-outbound-carrier-context)
exten => _1.,2,Congestion


If you use chan_local from a call-file and you want to pass channel variables into your context, make sure you append the '/n', because otherwise chan_local will 'optimize' itself out of the call-path, and the variables will get lost. i.e.

Local/00531234567@pbx becomes Local/00531234567@pbx/n

Local channels don't support state information (see hint) in Asterisk 1.4. For that you either need to use 1.6 or backport of state_interface for 1.4. Then you have to set call-limit for peers, and specify state_interface device when logging in agents. For more information please search for "asterisk queue state" on the asterisk-users mailinglist.

Be aware that your CDR data will become clutter with extra data; you might want to consider using NoCDR() and ResetCDR() to prevent this from happening.

See also

Go back to Asterisk channels

Created by: oej, Last modification: Fri 13 of Aug, 2010 (05:15 UTC) by JustRumours
Please update this page with new information, just login and click on the "Edit" or "Discussion" tab. Get a free login here: Register Thanks! - Find us on Google+