jump to navigation

Cheating around ‘include’ in Asterisk realtime July 17, 2007

Posted by bbarrett in Asterisk, func_odbc.
trackback

Asterisk’s realtime configuration has many benefits, no more dropped calls when changing minor things or adding users. You can put your entire dial plan into realtime… almost.

One of the biggest differences between extensions.conf and Asterisk’s Realtime dial plan is that one can no longer include other contexts into another context. This is the classic way of building an tiered dialling rule hierarchy, create the most restrictive context, then use ‘include’ to add more and more allowed numbers. E.g:

[emergency]
exten => 112,n,Dial(IAX/PSTN/112)


[local]
include => emergency
exten => _051.,n,Dial(IAX/PSTN/${EXTEN})


[national]
include => local
exten => _0[1-79].,n,Dial(IAX/PSTN/${EXTEN})


[mobile]
include => national
; etc for mobile, international and high rate numbers

If we wanted to store this in a database we have a few options.

  • We could copy all the extension logic in each context. Not really nice nor maintainable at all.
  • We could hard code the includes into extensions.conf before switching to realtime. I haven’t tried this, but maybe it would work. However it is unsuitable for our purposes because we want to make a PBX the customer can configure online, so if they try to add additional contexts then this will break. We want as close to 0 reloading as possible. Customers will share PBXs so there will be unique contexts created for each customer.

A workaround for the moment is to bypass Asterisk’s routing and lump all the users into the same context initially. This context will use some func_odbc magic dust to route users into the appropriate context. I created a table like so (text based key for illustrative purposes, you could use a numeric id instead if you like)

id regex context
emergency 112 emergency
local 112 051. emergency local
national 112 051. 05([1-7]|9). emergency local national

In the table the regex matches up with the context so that if you match the first regex your call will be routed to the first context. This is because func_odbc doesn’t seem to handle returning multiple rows at a time. There are ways to reduce the amount of repetition (chaining of ids to create “linked lists” of regex/context pairs perhaps) but for our purposes we are only experimenting in ways to get around these Asterisk limitations.

This way our dial plan is simple. Everyone shares the same context. This context reads the users permission id from the users account (all our SIP accounts are also stored in the database). We then read the regex and contexts from this table and loop to find a match. When a match is found, the user is placed in the correct context.

[routing_context]
exten => _[0-9a-z].,1,Set( permission=${ODBC_GETPERMISSION_BYCID(${CALLERID(all)
})})
exten => _[0-9a-z].,n,Set( tmp="${ODBC_GETREGEX_CONTEXT_BYPERMISSION(${permissio
n})}")
exten => _[0-9a-z].,n,Set(fullregexp="${CUT(tmp,\,,1)}")
exten => _[0-9a-z].,n,Set(context="${CUT(tmp,\,,2)}")
exten => _[0-9a-z].,n,Set(i=1)
exten => _[0-9a-z].,n,While(1)
exten => _[0-9a-z].,n,Set(regexp="${CUT(fullregexp, ,${i})}")
exten => _[0-9a-z].,n,ExecIf($["${regexp}" = ""]|Hangup)
exten => _[0-9a-z].,n,ExecIf( $[${REGEX("^(${regexp})" ${EXTEN})}]|Goto|${CUT(co
ntext, ,${i})}|${EXTEN}|1)
exten => _[0-9a-z].,n,Set(i=$[${i} + 1])
exten => _[0-9a-z].,n,EndWhile()
exten => _[0-9a-z].,n,Hangup()

It is a pity that there doesn’t seem to be an easier way to add contexts to the database without needing to change extensions.conf. However this way we can, however ugly the dial plan in extensions.conf needs to be.

Comments»

1. helderam - November 10, 2007

Hello,

I have tha same problem.

If know other way to solve the problem, let me know.

thanks,
Helder

2. Héctor - March 18, 2008

Hi,

Is there any new way to include context in realtime ?

I don’t find any other usefull info about this topic

3. Ish - September 22, 2008

Hi

You can include contexts to others in RealTime although you will need to learn some shell scripting

There is a file that is run every minute on the root crontab, on my setup it is

/usr/local/bin/db-ext.sh

this basically rewrites the extensions.conf and reloads the dial plan

It is in this file that you can add your own macros and get contexts to include other contexts


Leave a comment