These changes add the ability to run 'make asterisk.txt' just like the existing 'make asterisk.pdf' commands to generate a text document from the TeX files we have in the doc/tex/ directory. I've also updated a few of the .tex files because they weren't properly escaping certain characters so they would show up as Unicode characters (like [U+021C]). Made changes to the configure scripts so it would detect the catdvi program which is required to convert the .dvi file generated by latex. I've also added a few lines to the build_tools/prep_tarball script so that the text documentation gets generated and added to future tarballs of Asterisk releases. (closes issue #17220) Reported by: lmadsen Patches: asterisk.txt.patch uploaded by lmadsen (license 10) asterisk.txt.patch-v4 uploaded by pabelanger (license 224) Tested by: lmadsen, pabelanger git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@258351 65c4cc65-6c06-0410-ace0-fbb531ad65f3
509 lines
20 KiB
TeX
509 lines
20 KiB
TeX
\subsection{Introduction}
|
|
|
|
In Asterisk, Local channels are a method used to treat an extension in the
|
|
dialplan as if it were an external device. In essense, Asterisk will send the
|
|
call back into the dialplan as the destination of the call, versus sending the
|
|
call to a device.
|
|
|
|
Two of the most common areas where Local channels are used include members
|
|
configured for queues, and in use with callfiles. There are also other uses
|
|
where you want to ring two destinations, but with different information, such as
|
|
different callerID for each outgoing request.
|
|
|
|
\subsection{Examples}
|
|
|
|
Local channels are best demonstrated through the use of an example. Our first
|
|
example isn't terribly useful, but will demonstrate how Local channels can
|
|
execute dialplan logic by dialing from the Dial() application.
|
|
|
|
|
|
\subsection{Trivial Local channel example}
|
|
|
|
In our dialplan (extensions.conf), we can Dial() another part of the dialplan
|
|
through the use Local channels. To do this, we can use the following dialplan:
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
[devices]
|
|
exten => 201,1,Verbose(2,Dial another part of the dialplan via the Local chan)
|
|
exten => 201,n,Verbose(2,Outside channel: ${CHANNEL})
|
|
exten => 201,n,Dial(Local/201@extensions)
|
|
exten => 201,n,Hangup()
|
|
|
|
[extensions]
|
|
exten => 201,1,Verbose(2,Made it to the Local channel)
|
|
exten => 201,n,Verbose(2,Inside channel: ${CHANNEL})
|
|
exten => 201,n,Dial(SIP/some-named-extension,30)
|
|
exten => 201,n,Hangup()
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
The output of the dialplan would look something like the following. The output
|
|
has been broken up with some commentary to explain what we're looking at.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
-- Executing [201@devices:1] Verbose("SIP/my_desk_phone-00000014", "2,Dial another part of the dialplan via the
|
|
Local chan") in new stack
|
|
== Dial another part of the dialplan via the Local chan
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
We dial extension 201 from SIP/my\_desk\_phone which has entered the [devices]
|
|
context. The first line simply outputs some information via the Verbose()
|
|
application.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
-- Executing [201@devices:2] Verbose("SIP/my_desk_phone-00000014",
|
|
"2,Outside channel: SIP/my_desk_phone-00000014") in new stack
|
|
== Outside channel: SIP/my_desk_phone-00000014
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
The next line is another Verbose() application statement that tells us our
|
|
current channel name. We can see that the channel executing the current dialplan
|
|
is a desk phone (aptly named 'my\_desk\_phone').
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
-- Executing [201@devices:3] Dial("SIP/my_desk_phone-00000014", "Local/201@extensions") in new stack
|
|
-- Called 201@extensions
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
Now the third step in our dialplan executes the Dial() application which calls
|
|
extension 201 in the [extensions] context of our dialplan. There is no
|
|
requirement that we use the same extension number -- we could have just as
|
|
easily used a named extension, or some other number. Remember that we're dialing
|
|
another channel, but instead of dialing a device, we're "dialing" another part
|
|
of the dialplan.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
-- Executing [201@extensions:1] Verbose("Local/201@extensions-7cf4;2", "2,Made it to the Local
|
|
channel") in new stack
|
|
== Made it to the Local channel
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
Now we've verified we've dialed another part of the dialplan. We can see the
|
|
channel executing the dialplan has changed to Local/201@extensions-7cf4;2. The
|
|
part '-7cf4;2' is just the unique identifier, and will be different for you.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
-- Executing [201@extensions:2] Verbose("Local/201@extensions-7cf4;2", "2,Inside channel:
|
|
Local/201@extensions-7cf4;2") in new stack
|
|
== Inside channel: Local/201@extensions-7cf4;2
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
Here we use the Verbose() application to see what our current channel name is.
|
|
As you can see the current channel is a Local channel which we created from our
|
|
SIP channel.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
-- Executing [201@extensions:3] Dial("Local/201@extensions-7cf4;2", "SIP/some-named-extension,30") in new stack
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
And from here, we're using another Dial() application to call a SIP device
|
|
configured in sip.conf as [some-named-extension].
|
|
|
|
Now that we understand a simple example of calling the Local channel, let's
|
|
expand upon this example by using Local channels to call two devices at the same
|
|
time, but delay calling one of the devices.
|
|
|
|
\subsection{Delay dialing devices}
|
|
|
|
Lets say when someone calls extension 201, we want to ring both the desk phone
|
|
and their cellphone at the same time, but we want to wait about 6 seconds to
|
|
start dialing the cellphone. This is useful in a situation when someone might be
|
|
sitting at their desk, but don't want both devices ringing at the same time, but
|
|
also doesn't want to wait for the full ring cycle to execute on their desk phone
|
|
before rolling over to their cellphone.
|
|
|
|
The dialplan for this would look something like the following:
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
[devices]
|
|
exten => 201,1,Verbose(2,Call desk phone and cellphone but with delay)
|
|
exten => 201,n,Dial(Local/deskphone-201@extensions&Local/cellphone-201@extensions,30)
|
|
exten => 201,n,Voicemail(201@default,${IF($[${DIALSTATUS} = BUSY]?b:u)})
|
|
exten => 201,n,Hangup()
|
|
|
|
[extensions]
|
|
; Dial the desk phone
|
|
exten => deskphone-201,1,Verbose(2,Dialing desk phone of extension 201)
|
|
exten => deskphone-201,n,Dial(SIP/0004f2040001) ; SIP device with MAC address
|
|
; of 0004f2040001
|
|
|
|
; Dial the cellphone
|
|
exten => cellphone-201,1,Verbose(2,Dialing cellphone of extension 201)
|
|
exten => cellphone-201,n,Verbose(2,-- Waiting 6 seconds before dialing)
|
|
exten => cellphone-201,n,Wait(6)
|
|
exten => cellphone-201,n,Dial(DAHDI/g0/14165551212)
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
When someone dials extension 201 in the [devices] context, it will execute the
|
|
Dial() application, and call two Local channels at the same time:
|
|
|
|
\begin{itemize}
|
|
\item Local/deskphone-201@extensions
|
|
\item Local/cellphone-201@extensions
|
|
\end{itemize}
|
|
|
|
It will then ring both of those extensions for 30 seconds before rolling over to
|
|
the Voicemail() application and playing the appropriate voicemail recording
|
|
depending on whether the \$\{DIALSTATUS\} variable returned BUSY or not.
|
|
|
|
When reaching the deskphone-201 extension, we execute the Dial() application
|
|
which calls the SIP device configured as '0004f204001' (the MAC address of the
|
|
device). When reaching the cellphone-201 extension, we dial the cellphone via
|
|
the DAHDI channel using group zero (g0) and dialing phone number 1-416-555-1212.
|
|
|
|
\subsection{Dialing destinations with different information}
|
|
|
|
With Asterisk, we can place a call to multiple destinations by separating the
|
|
technology/destination pair with an ampersand (\&). For example, the following
|
|
Dial() line would ring two separate destinations for 30 seconds:
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
exten => 201,1,Dial(SIP/0004f2040001&DAHDI/g0/14165551212,30)
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
That line would dial both the SIP/0004f2040001 device (likely a SIP device on
|
|
the network) and dial the phone number 1-416-555-1212 via a DAHDI interface. In
|
|
our example though, we would be sending the same callerID information to both
|
|
end points, but perhaps we want to send a different callerID to one of the
|
|
destinations?
|
|
|
|
We can send different callerIDs to each of the destinations if we want by using
|
|
the Local channel. The following example shows how this is possible because we
|
|
would Dial() two different Local channels from our top level Dial(), and that
|
|
would then execute some dialplan before sending the call off to the final
|
|
destinations.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
[devices]
|
|
exten => 201,1,NoOp()
|
|
exten => 201,n,Dial(Local/201@internal&Local/201@external,30)
|
|
exten => 201,n,Voicemail(201@default,${IF($[${DIALSTATUS} = BUSY]?b:u)})
|
|
exten => 201,n,Hangup()
|
|
|
|
[internal]
|
|
exten => 201,1,Verbose(2,Placing internal call for extension 201)
|
|
exten => 201,n,Set(CALLERID(name)=From Sales)
|
|
exten => 201,n,Dial(SIP/0004f2040001,30)
|
|
|
|
[external]
|
|
exten => 201,1,Verbose(2,Placing external call for extension 201)
|
|
exten => 201,n,Set(CALLERID(name)=Acme Cleaning)
|
|
exten => 201,n,Dial(DAHDI/g0/14165551212)
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
With the dialplan above, we've sent two different callerIDs to the destinations:
|
|
|
|
\begin{itemize}
|
|
\item "From Sales" was sent to the local device SIP/0004f2040001
|
|
\item "Acme Cleaning" was sent to the remote number 1-416-555-1212 via DAHDI
|
|
\end{itemize}
|
|
|
|
Because each of the channels is independent from the other, you could perform
|
|
any other call manipulation you need. Perhaps the 1-416-555-1212 number is a
|
|
cell phone and you know you can only ring that device for 18 seconds before the
|
|
voicemail would pick up. You could then limit the length of time the external
|
|
number is dialed, but still allow the internal device to be dialed for a longer
|
|
period of time.
|
|
|
|
\subsection{Using callfiles and Local channels}
|
|
|
|
Another example is to use callfiles and Local channels so that you can execute
|
|
some dialplan prior to performing a Dial(). We'll construct a callfile which
|
|
will then utilize a Local channel to lookup a bit of information in the AstDB
|
|
and then place a call via the channel configured in the AstDB.
|
|
|
|
First, lets construct our callfile that will use the Local channel to do some
|
|
lookups prior to placing our call. More information on constructing callfiles is
|
|
located in the doc/callfiles.txt file of your Asterisk source.
|
|
|
|
Our callfile will simply look like the following:
|
|
|
|
\begin{verbatim}
|
|
Channel: Local/201@devices
|
|
Application: Playback
|
|
Data: silence/1&tt-weasels
|
|
\end{verbatim}
|
|
|
|
Add the callfile information to a file such as 'callfile.new' or some other
|
|
appropriately named file.
|
|
|
|
Our dialplan will perform a lookup in the AstDB to determine which device to
|
|
call, and will then call the device, and upon answer, Playback() the silence/1
|
|
(1 second of silence) and the tt-weasels sound files.
|
|
|
|
Before looking at our dialplan, lets put some data into AstDB that we can then
|
|
lookup from the dialplan. From the Asterisk CLI, run the following command:
|
|
|
|
\begin{verbatim}
|
|
*CLI> database put phones 201/device SIP/0004f2040001
|
|
\end{verbatim}
|
|
|
|
We've now put the device destination (SIP/0004f2040001) into the 201/device key
|
|
within the phones family. This will allow us to lookup the device location for
|
|
extension 201 from the database.
|
|
|
|
We can then verify our entry in the database using the 'database show' CLI
|
|
command:
|
|
|
|
\begin{verbatim}
|
|
*CLI> database show
|
|
/phones/201/device : SIP/0004f2040001
|
|
\end{verbatim}
|
|
|
|
Now lets create the dialplan that will allow us to call SIP/0004f2040001 when we
|
|
request extension 201 from the [extensions] context via our Local channel.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
[devices]
|
|
exten => 201,1,NoOp()
|
|
exten => 201,n,Set(DEVICE=${DB(phones/${EXTEN}/device)})
|
|
exten => 201,n,GotoIf($[${ISNULL(${DEVICE})}]?hangup) ; if nothing returned,
|
|
; then hangup
|
|
exten => 201,n,Dial(${DEVICE},30)
|
|
exten => 201,n(hangup(),Hangup()
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
Then, we can perform a call to our device using the callfile by moving it into
|
|
the /var/spool/asterisk/outgoing/ directory.
|
|
|
|
\begin{verbatim}
|
|
# mv callfile.new /var/spool/asterisks/outgoing
|
|
\end{verbatim}
|
|
|
|
Then after a moment, you should see output on your console similar to the
|
|
following, and your device ringing. Information about what is going on during
|
|
the output has also been added throughout.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
-- Attempting call on Local/201@devices for application Playback(silence/1&tt-weasels) (Retry 1)
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
You'll see the line above as soon as Asterisk gets the request from the
|
|
callfile.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
-- Executing [201@devices:1] NoOp("Local/201@devices-ecf0;2", "") in new stack
|
|
-- Executing [201@devices:2] Set("Local/201@devices-ecf0;2", "DEVICE=SIP/0004f2040001") in new stack
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
This is where we performed our lookup in the AstDB. The value of
|
|
SIP/0004f2040001 was then returned and saved to the DEVICE channel variable.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
-- Executing [201@devices:3] GotoIf("Local/201@devices-ecf0;2", "0?hangup") in new stack
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
We perform a check to make sure \$\{DEVICE\} isn't NULL. If it is, we'll just
|
|
hangup here.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
-- Executing [201@devices:4] Dial("Local/201@devices-ecf0;2", "SIP/0004f2040001,30") in new stack
|
|
-- Called 000f2040001
|
|
-- SIP/0004f2040001-00000022 is ringing
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
Now we call our device SIP/0004f2040001 from the Local channel.
|
|
|
|
\begin{verbatim}
|
|
-- SIP/0004f2040001-00000022 answered Local/201@devices-ecf0;2
|
|
\end{verbatim}
|
|
|
|
We answer the call.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
> Channel Local/201@devices-ecf0;1 was answered.
|
|
> Launching Playback(silence/1&tt-weasels) on Local/201@devices-ecf0;1
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
We then start playing back the files.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
-- <Local/201@devices-ecf0;1> Playing 'silence/1.slin' (language 'en')
|
|
== Spawn extension (devices, 201, 4) exited non-zero on 'Local/201@devices-ecf0;2'
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
At this point we now see the Local channel has been optimized out of the call
|
|
path. This is important as we'll see in examples later. By default, the Local
|
|
channel will try to optimize itself out of the call path as soon as it can. Now
|
|
that the call has been established and audio is flowing, it gets out of the way.
|
|
|
|
\begin{astlisting}
|
|
\begin{verbatim}
|
|
-- <SIP/0004f2040001-00000022> Playing 'tt-weasels.ulaw' (language 'en')
|
|
[Mar 1 13:35:23] NOTICE[16814]: pbx_spool.c:349 attempt_thread: Call completed to Local/201@devices
|
|
\end{verbatim}
|
|
\end{astlisting}
|
|
|
|
We can now see the tt-weasels file is played directly to the destination
|
|
(instead of through the Local channel which was optimized out of the call path)
|
|
and then a NOTICE stating the call was completed.
|
|
|
|
\subsection{Understanding When To Use /n}
|
|
|
|
Lets take a look at an example that demonstrates when the use of the /n
|
|
directive is necessary. If we spawn a Local channel which does a Dial()
|
|
to a SIP channel, but we use the L() option (which is used to limit the
|
|
amount of time a call can be active, along with warning tones when the
|
|
time is nearly up), it will be associated with the Local channel,
|
|
which is then optimized out of the call path, and thus won't perform
|
|
as expected.
|
|
|
|
This following dialplan will not perform as expected.
|
|
|
|
\begin{verbatim}
|
|
[services]
|
|
exten => 2,1,Dial(SIP/PHONE\_B,,L(60000:45000:15000))
|
|
|
|
[internal]
|
|
exten => 4,1,Dial(Local/2@services)
|
|
\end{verbatim}
|
|
|
|
By default, the Local channel will try to optimize itself out of the call path.
|
|
This means that once the Local channel has established the call between the
|
|
destination and Asterisk, the Local channel will get out of the way and let
|
|
Asterisk and the end point talk directly, instead of flowing through the Local
|
|
channel.
|
|
|
|
This can have some adverse effects when you're expecting information to be
|
|
available during the call that gets associated with the Local channel. When the
|
|
Local channel is optimized out of the call path, any Dial() flags, or channel
|
|
variables associated with the Local channel are also destroyed and are no longer
|
|
available to Asterisk.
|
|
|
|
We can force the Local channel to remain in the call path by utilizing the /n
|
|
directive. By adding /n to the end of the channel definition, we can keep the
|
|
Local channel in the call path, along with any channel variables, or other
|
|
channel specific information.
|
|
|
|
In order to make this behave as we expect (limiting the call), we would change:
|
|
|
|
\begin{verbatim}
|
|
[internal]
|
|
exten => 4,1,Dial(Local/2@services)
|
|
\end{verbatim}
|
|
|
|
...into the following:
|
|
|
|
\begin{verbatim}
|
|
[internal]
|
|
exten => 4,1,Dial(Local/2@services/n)
|
|
\end{verbatim}
|
|
|
|
By adding /n to the end, our Local channel will now stay in the call path and
|
|
not go away.
|
|
|
|
Why does adding the /n option all of a suddon make the 'L' option work? First
|
|
we need to show an overview of the call flow that doesn't work properly, and
|
|
discuss the information associated with the channels:
|
|
|
|
\begin{enumerate}
|
|
\item SIP device PHONE\_A calls Asterisk via a SIP INVITE
|
|
\item Asterisk accepts the INVITE and then starts processing dialplan logic in the [internal] context
|
|
\item Our dialplan calls Dial(Local/2@services) -- notice no /n
|
|
\item The Local channel then executes dialplan at extension 2 within the [services] context
|
|
\item Extension 2 within [services] then performs Dial() to PHONE\_B with the line: Dial(SIP/PHONE\_B,,L(60000:45000:15000))
|
|
\item SIP/PHONE\_B then answers the call
|
|
\item Even though the L option was given when dialing the SIP device, the L information is stored in the channel that is doing the Dial() which is the Local channel, and not the endpoint SIP channel.
|
|
\item The Local channel in the middle, containing the information for tracking the time allowance of the call, is then optimized out of the call path, losing all information about when to terminate the call.
|
|
\item SIP/PHONE\_A and SIP/PHONE\_B then continue talking indefinitely.
|
|
\end{enumerate}
|
|
|
|
Now, if we were to add /n to our dialplan at step three (3) then we would force the
|
|
Local channel to stay in the call path, and the L() option associated with the
|
|
Dial() from the Local channel would remain, and our warning sounds and timing
|
|
would work as expected.
|
|
|
|
There are two workarounds for the above described scenario:
|
|
|
|
\begin{enumerate}
|
|
\item Use what we just described, Dial(Local/2@services/n) to cause the Local
|
|
channel to remain in the call path so that the L() option used inside the
|
|
Local channel is not discarded when optimization is performed.
|
|
\item Place the L() option at the outermost part of the path so that when the middle
|
|
is optimized out of the call path, the information required to make L() work
|
|
is associated with the outside channel. The L information will then be stored
|
|
on the calling channel, which is PHONE\_A. For example:
|
|
|
|
\begin{verbatim}
|
|
[services]
|
|
exten => 2,1,Dial(SIP/PHONE_B)
|
|
|
|
[internal]
|
|
exten => 4,1,Dial(Local/2@services,,L(60000:45000:15000));
|
|
\end{verbatim}
|
|
\end{enumerate}
|
|
|
|
\subsection{Local channel modifiers}
|
|
|
|
There are additional modifiers for the Local channel as well. They include:
|
|
|
|
\begin{itemize}
|
|
\item 'n' -- 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 and
|
|
one audio frame passes, 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.
|
|
|
|
\item 'j' -- Adding "/j" at the end of the string allows you to use the generic
|
|
jitterbuffer on incoming calls going to Asterisk applications. For
|
|
example, this would allow you to use a jitterbuffer for an incoming
|
|
SIP call to Voicemail by putting a Local channel in the middle. The
|
|
'j' option must be used in conjunction with the 'n' option to make
|
|
sure that the Local channel does not get optimized out of the call.
|
|
|
|
This option is available starting in the Asterisk 1.6.0 branch.
|
|
|
|
\item 'm' -- Using the "/m" option will cause the Local channel to forward music on
|
|
hold (MoH) start and stop requests. Normally the Local channel acts on
|
|
them and it is started or stopped on the Local channel itself. This
|
|
options allows those requests to be forwarded through the Local
|
|
channel.
|
|
|
|
This option is available starting in the Asterisk 1.4 branch.
|
|
|
|
\item 'b' -- The "/b" option causes the Local channel to return the actual channel
|
|
that is behind it when queried. This is useful for transfer scenarios
|
|
as the actual channel will be transferred, not the Local channel.
|
|
|
|
This option is available starting in the Asterisk 1.6.0 branch.
|
|
\end{itemize}
|