Training - Technical Support - Asterisk CLI

This course will cover the basics of the Asterisk CLI. At the end of this course you should be familiar with reading the output of the CLI and running basic commands.

Introduction to the Asterisk CLI

What is the Asterisk CLI?

The Command Line Interface, or console for Asterisk, serves a variety of purposes for an Asterisk administrator. Some of these are:

  • Obtaining information on Asterisk configuration and components
  • Affecting system configuration
  • Seeing log output, errors and warnings in real-time
  • Viewing embedded help documentation such as for APIs, applications, functions and module configuration

In the context of a Lightspeed Voice Technical Support Representative, you will use the CLI primarily for troubleshooting. It allows you to verify settings and follow the processing of phone calls through every part of the routing logic. 

Why do you want to learn more about it? Well that's simple. Becoming proficient with the Asterisk CLI will make you more efficient at your job. You'll be able to track down pesky issues that mystified you in the past and have a much deeper understanding of how our phone system works. The only negative is that it's like learning that Santa isn't real - the magic that those level 2 guys perform won't seem so magical anymore. 

Methods of accessing the Asterisk CLI

Before using the Asterisk CLI, you will need to remote into the server in question and access the Linux CLI. Any commands discussed from here on out assume that you start from the Linux CLI. 
SSH

To enter the Asterisk CLI, simply type the command asterisk -rvvvvvv (more Vs increase the Verbosity, and less than 3 may cause you to miss important information). Jay CLI view

You can also run commands on the Asterisk CLI without actually entering it. This can be very useful when you need time to look at an output without the "spam" that comes while on the CLI. This is done by typing asterisk -rx "<insert command here>"core show channels

Reading the spam - it's not as complicated as it looks.

We know, it looks complicated. Scary even.

At first glance, this view looks like it's in another language all together and it could take years to learn. In reality, it is speaking its own language, but we don't have to learn it to understand it! Asterisk has a specific set of guidelines (or logic) for how to handle phone calls of all types, which is called "Dialplan." As it progresses through the dialplan, it reports every step in the log, which can be seen realtime through the CLI. 

CLI view

Understanding the Dialplan

Asterisk works efficiently by reusing a relatively small set of macros to complete pretty much any action wished. Each of these macros contains logic which completes a specific function. Example: If you need to set or check the Caller ID on a channel, there's a macro for that. Each phone call goes on a path through these macros, often times determined by the "call route" that's been setup for a particular inbound route. 

Each macro has a human-readable name and each "step" of the macro is clearly visible in the log. Knowing this makes the log a bit easier to understand. Let's break down a single line of the CLI to understand the "zones" of a message.

The above line is telling us that the system is Executing line 1 of macro-outbound-callerid for a channel named SIP/335-000001e6, and that line 1 Sets a variable. The trick here is not to get hung up on information that we don't really need to know. What is the variable CALLERPRES? Well we could google that up in no time if we wish, but it's not essential to what we're doing. 

Now let's look at more of this macro:

In the very first line, we see that macro-dialout-trunk has decided to initiate a Macro called outbound-callerid. On the very next line, macro-outbound-callerid begins. Finally on the last line, it returns back to the next line of macro-dialout-trunk since macro-outbound-callerid is finished running. 

Even though it would be complicated to understand every single step of this macro, we are able to pull out some simple information that we care about without delving into every line. All we really need to be able to take from this is that the outbound CID which got set when it ran is +19415643010. 

In the below example, we can see macro-dialout-trunk is initiating a Dial command, sending a call from the channel SIP/335-000001e6 to SIP/SEoutbound/13523534444. To state it simply, 335 is calling 352-353-4444. 

 

 

Let's trace a call

Now that we have a basic understanding of how the diaplan works, let's try tracing a call.

First, here's the full readout of a call. If this seems daunting, that's ok. We're going to simplify it. 

 

Breaking it down

Would it take us hours to read and understand every single line of that call? Probably. However, we don't need to do that. A quick skim gives us a clear overview of what's going on.

On the first line we see that someone (we don't know who yet) has called +19415643010, and that the call routed through Athos.

-- Executing [[email protected]:1] Set("SIP/Athos-00000231", "__FROM_DID=+19415643010") in new stack

If we scan a few lines further down, we see who made that call:

-- Executing [[email protected]:4] ExecIf("SIP/Athos-00000231", "0 ?Set(CALLERID(name)=+13523534444)") in new stack

Next, it heads on to the Call Recording module and determines that it's set to FORCE, ALWAYS. 

-- Goto (ext-callrecording,1,1)

    -- Executing [[email protected]:1] Gosub("SIP/Athos-00000231", "sub-record-check,s,1(force,+19415643010,always)") in new stack

This triggers Call Recording to begin, and sets some CDR variables that we'll later be able to spot in the CDR reports.

== Begin MixMonitor Recording SIP/Athos-00000231

    -- Executing [[email protected]:4] Set("SIP/Athos-00000231", "CDR(recordingfile)=force-+19415643010-unknown-20160725-173606-1469482566.2878.WAV") in new stack

    -- Executing [[email protected]:5] Set("SIP/Athos-00000231", "CDR(userfield)=/var/spool/asterisk/monitor/2016/07/25/force-+19415643010-unknown-20160725-173606-1469482566.2878.WAV") in new stack

Now Call Recording sends it over to the next module in our route, the IVR. Here, it tells us the timeout period and what message is being played, as well as what option they end up choosing in the IVR. In this case they chose option 1 which goes off to a daynight (call flow control) option. How can we tell they chose option 1? It says [email protected] - that is similar to [email protected] It is executing the number that was entered in the IVR instead of a phone call in this case.

 -- Executing [[email protected]:2] Goto("SIP/Athos-00000231", "ivr-1,s,1") in new stack
    -- Goto (ivr-1,s,1)

 -- Executing [[email protected]:9] Set("SIP/Athos-00000231", "IVR_MSG=custom/IVR-Intro-Main") in new stack
    -- Executing [[email protected]:10] Set("SIP/Athos-00000231", "TIMEOUT(digit)=3") in new stack
    -- Digit timeout set to 3.000
    -- <SIP/Athos-00000231> Playing 'custom/IVR-Intro-Main.slin' (language 'en')
    -- Executing [[email protected]:1] Goto("SIP/Athos-00000231", "app-daynight,00,1") in new stack

The Call Flow Control (also known as daynight) module now sends the call off to another IVR based on whether it's red or green (night or day). 

-- Goto (app-daynight,00,1)
    -- Executing [[email protected]:1] GotoIf("SIP/Athos-00000231", "0?ivr-17,s,1:ivr-15,s,1") in new stack
    -- Goto (ivr-15,s,1)

Again this IVR tells us what message it's playing, as well as the timeout, and in this case they choose option "2" from this IVR which is a Time Conditions module destination. 

 -- Digit timeout set to 3.000
    -- <SIP/Athos-00000231> Playing 'custom/IVR-Option-1-Breakout.slin' (language 'en')
    -- Executing [[email protected]:1] Goto("SIP/Athos-00000231", "timeconditions,7,1") in new stack

 

This time condition appears to be a "holiday" one, as evidenced by the dates that it's checking against. It forwards us on to the next time condition when it doesn't match. 

-- Executing [[email protected]:1] GotoIfTime("SIP/Athos-00000231", "00:00-23:59,*,25,dec?truestate") in new stack
    -- Executing [[email protected]:2] GotoIfTime("SIP/Athos-00000231", "00:00-23:59,*,24,nov?truestate") in new stack
    -- Executing [[email protected]:3] GotoIfTime("SIP/Athos-00000231", "00:00-23:59,*,05,sep?truestate") in new stack
    -- Executing [[email protected]:4] GotoIfTime("SIP/Athos-00000231", "00:00-23:59,*,04,jul?truestate") in new stack
    -- Executing [[email protected]:5] GotoIfTime("SIP/Athos-00000231", "00:00-23:59,*,30,may?truestate") in new stack
    -- Executing [[email protected]:8] GotoIf("SIP/Athos-00000231", "1?timeconditions,3,1") in new stack

The next time condition matches almost immediately because these logs were gathered on a Monday and the first hit in the timegroup happens to be Monday. It is now directed onto another IVR.

-- Executing [[email protected]:1] GotoIfTime("SIP/Athos-00000231", "08:30-18:30,mon,*,*?truestate") in new stack
    -- Executing [[email protected]:13] GotoIf("SIP/Athos-00000231", "1?ivr-8,s,1") in new stack

In this case, nothing is pressed in the IVR and it goes to the 't' destination which is short for the timeout destination. In this IVR, the timeout destination is a Queue (230). 

 -- Goto (ivr-8,s,1)
    -- Digit timeout set to 3.000
    -- <SIP/Athos-00000231> Playing 'custom/IVR-LNP-Open.slin' (language 'en')
    -- Timeout on SIP/Athos-00000231, going to 't'
    -- Executing [[email protected]:1] Goto("SIP/Athos-00000231", "ext-queues,230,1") in new stack

 

Once it hits the queue, lots of minor checks are performed (CID, recording, prepend-CID, etc) before it goes on to ring an extension.

-- Goto (ext-queues,230,1)

-- Executing [[email protected]:1] Set("Local/[email protected];2", "QAGENT=305") in new stack

 -- Goto (from-internal,305,1)

After more processing, extension 305 finally rings to answer the call.

  -- Called SIP/305

-- SIP/305-00000232 is ringing

However, the caller hangs up before 305 can answer.

-- Executing [[email protected]:1] Macro("SIP/Athos-00000231", "hangupcall,") in new stack

Multiple calls

Now that we've gone through a call and learned to spot the key lines of code, we'll talk about what to do when multiple calls are being processed at the same time. 

This is actually a lot simpler than you might think - if you remember our walkthrough, you'll have noticed that every single line contains the Channel number of the call. That's our key to separating calls from each other. Simply look for your call's channel and look at lines that have that channel. 

-- Executing [[email protected]:1] Macro("SIP/Athos-00000231", "hangupcall,") in new stack

Does it have to be realtime?

The most useful thing about being able to read the Asterisk log output is this - it's all recorded in the /var/log/asterisk folder! We keep a 7-day rotation of the /var/log/asterisk/full file which contains the Asterisk log output. 

If a customer tells you that they had a problem with a call earlier in the day, you should now be able to search the log for that file (I like to start with either the phone number or the timestamp from CDR) and go through it. It's always better to do it this way if it's an option, rather than having the customer try to recreate it while you watch the Asterisk CLI. 

Useful commands

Here are a few (but not all) useful commands.

Here are a few (but not all) useful commands. Feel free to copy and paste to your own notes.

asterisk -rvvvvv - This is the command to enter the Asterisk Command Line Interface. This tool also provides a real time view of the inner workings of Asterisk. More vs result in more verbosity up to a certain point. Never simply type asterisk -rv because you will miss out on some information.

asterisk -rx "<insert your command here>" - This allows you to run an Asterisk CLI command directly from the Linux CLI, avoiding the spam that normally comes with being in the asterisk CLI. Example: asterisk -rx "sip show peers"

All commands from here down are Asterisk CLI commands, and would be run with either asterisk -rx "command" or directly on the asterisk CLI accessed through asterisk -rvvvvv. 

core show help - Shows ALL possible commands that can be run from the CLI.

core restart when convenient - A restart of Asterisk will be initiated when call volume has hit zero. This is very useful when you need to restart asterisk on a busy server and don't want to interrupt any active calls.

sip show peers - This will show a simple, condensed view of all current extensions and trunks (peers). You can see their registration status, originating IP address, and registration port.

sip show peer <name/username> - This will show a detailed summary of all information gathered about a peer. This will include the useragent (type of phone) and often even the internal IP address of the phone. Example: sip show peer 101

core show channels - This command shows a list of all currently open channels on the system. A typical phone call between two parties consists of two channels. One channel is for the remote side and the other is for the local side. This is a simple way to check if there are any active calls going, and is also a method to find the channel number of a channel that you wish to manually hang up. 

channel request hangup <channel> - This will manually hangup a channel, the name of which can be found in "core show channels" readout - example: channel request hangup SIP/302-000000af

database show - This command will show the entire asterisk database. It can be used to show DND state, forwarding state, set cidname, and lots more. We often pipe this command into a grep - example : asterisk -rx "database show" | grep 101 - this will only show results that have "101" somewhere in the line.

database showkey - This command will show only one key instead of the whole shebang. Example: database showkey cidname

 

Comprehension Test

What command would you use to get an overview of all active calls on the system without having to view the CLI "spam"?

  • From the Asterisk CLI> sip show peers
  • From the Linux CLI> asterisk -rx "core show channels"
  • From the Linux CLI> asterisk -rvvvvvvv core show channels
  • From the Asterisk CLI> core show channels
  • From the Linux CLI> asterisk -rx "show active calls"

Using the screenshot, what is the Channel for this call?

Use the attached image

  • This is a phone call to extension 335
  • This call was answered
  • The call's next destination is an IVR
  • The caller hung up while listening to the busy recording of a VM box
  • The caller's number is 352-353-4444

Click on the line where the caller makes a selection in ivr-1.

Enter all data *exactly* as it's presented in the log.

This call is from number to number .

Call recording is set to  for this call.

The name of the IVR message being played is .

Use the following image

  • ivr-1 has the setting "Direct Dial" set to Disabled.
  • This was an outbound call from 9415643010 to 3523534444