Asterisk

I've been playing with telephones since I was a small child, and I haven't stopped yet. These days I get paid for doing it.

Nearly all the telephones I play with now use the SIP protocol, and I've been running a number of Asterisk servers for several years, partly because it enables me to be available on several different numbers (which are 'based' in several different countries) no matter where I am at the time.

Asterisk-based systems can be nicely scalable, provided you respect what Asterisk is good at, and what it isn't good at, and substitute appropriate components in the latter cases (FreeSwitch and Kamailio being good examples).

Asterisk is good as a switching platform (dialplan, call routing) and as a SIP server (for phones to register to) - it's not so good as a SIP client (for registering to SIP servers). FreeSwitch is better for that. Use the right tool for the job.

Dialling using SIP credentials

Asterisk can play the rôle of a SIP client (ie: like a telephone) and communicate to another SIP server (maybe Asterisk, maybe not), and it can either REGISTER in order to receive incoming calls, or it can send INVITEs to place outgoing calls (or both).

REGISTER needs to be in sip.conf (or the database equivalent), and most documentation will tell you that you need to create a peer in sip.conf in order to be able to send INVITEs.

However, this is not always convenient. For example, I have a requirement to create a context which can be called using AMI Originate, passing SIP credentials in as variables, and then to place a call through an arbitrary server using those credentials (the purpose in my case being to verify that someone has given me working credentials before I go ahead and configure them on a production platform).

Finding out how to use the Dial() command with SIP credentials is not easy, so here's how you do it:

Set(CALLERID(num)=${SIPuser})
Dial(SIP/${SIPdial}:${SIPpass}::${SIPuser}@${SIPhost})

That will place a call to SIPdial via SIPhost, authenticating as user SIPuser with password SIPpass.

Note that a bug in Asterisk (confirmed in ver 13.14.1 and 16.2.1) means that this command will fail if there is a ! character anywhere in the dial string (the most likely place being the password).

I hope this helps someone out there spend less time than I did trying to work out how to do this.

Weird lack of error messages

Sometimes you can get Asterisk into a state where it doesn't even acknowledge that a perfectly standard command even exists, for example:

CLI> sip show peers
No such command 'sip show peers' (type 'core show help sip show' for other possible commands)

One of the easiest ways to do this is to have a #include macro in a configuration file somewhere, referencing a file which doesn't exist.

The standard

/etc/init.d/asterisk restart

won't even tell you there's a problem, never mind what the problem is - you have to do a careful search of the log files in /var/log/asterisk to find out what it thinks is wrong.

Asterisk Extension Language

AEL is a way of writing Asterisk dialplans in a more sensible language.

However, it has very rudimentary documentation, so here are some of my own notes on how to use it.

The syntax and keywords of AEL are defined in BNF, and there are some example pages of the commands.

AEL can be regarded as a meta-language for writing Asterisk dialplans, because you can write them in a way that looks like a normal programming language (including block structures), and the result then gets compiled into the standard Asterisk dialplan language (with numbered lines, and GOTO statements everywhere, looking, as the Asterisk language always does, like BASIC from the 1970s.

If you issue the command dialplan show Asterisk will show you what your AEL has been compiled into, not the original AEL.

There's also a useful tool aelparse which will take your AEL dialplan and tell you whether it has syntax errors etc., and if not, can output the compiled version (ie: 1970s BASIC) into a file for you. This allows you to check AEL dialplans without having to load them into Asterisk.

I came to AEL after many many years of writing standard Asterisk dialplans (and in fact only discovered it some time after I had given serious thought to what would effectively have been creating AEL myself). Once I decided that I would like to use it, this meant converting my old dialplans into AEL, so to deal with much of the tedium for this I wrote a Bash script which does a lot (but not all) of the work for you.

Neat things which AEL adds to dialplans

You can use the following constructs in AEL dialplans, which are nowhere near as neat and tidy to create in standard Asterisk language:

  • if () … else
    • but no elif :(
  • switch () casedefault:
    • including break
  • for (a; b; c) …
    • including break and continue
  • while () …
    • including break and continue
  • /* … */
    • multi-line comments (including containing // single-line comments)

The return() statement can also be used anywhere (not just in a subroutine or macro) and goes to the end of the macro or context.

Caveats

AEL (and its documentation) is far from perfect.

  • For one thing, as soon as you start using any of the above constrcutions in your dialplans, AEL will liberally pepper the output with things like "NoOp(Finish if_switch_SwitchTest_5410)" which means the phrases (which you didn't put into the original dialplan) likely end up in your log files too (depending on your chosen verbosity of logging).
  • The documentation for the "switch" statement states that "Neither the switch nor case values are wrapped in $[ ]; they can be constants, or ${var} type references only."
    • However variables can only be global variables - standard ones simply don't work.
  • Simple assignments such as "a=42" may seem nicer and more in keeping with other languages than "Set(a=42)" but you need to be very aware that the right-hand side of all such assignments get automatically wrapped in "$[ … ]", meaning that any arithmetic symbols such as + - * / which exist inside the values of any variables will get evaluated and may give you a surprise.

Go up
Return to main index.