Asterisk RealTime Extensions
(This has got to be the coolest addition I've seen to RealTime. Big kudos to Mark on this.)
Extconfig.conf Setup
Add the following line, swapping your own personal values if you wish:
extensions => mysql,asterisk,extensions_table
You can change mysql to odbc if you want to use odbc.
You can change asterisk to be the name of your database.
You can change extensions_table to be the name of the extensions table we will create below.
modules.conf Setup
Don't forget to load the proper modules or Strange Things (TM) will happen.autoload=yes
or explicitly list them out:
load => res_config_mysql.so
load => app_realtime.so
load => func_realtime.so
load => pbx_realtime.so
load => app_realtime.so
load => func_realtime.so
load => pbx_realtime.so
(props to Corydon76 for setting a few of us straight)
Extensions.conf Setup
The way RealTime Extensions work is through a switch statement in the dialplan. Here is an example of my context:[test]
;
; switch => Realtime/[context]@[family][/options]
; If context is not given, current context is default
; If family is not given, family of 'extensions' is default
;
switch => Realtime/mycontext@realtime_ext
This tells Asterisk that any call into the 'test' context are to be switched to RealTime using the context "mycontext" and the family name "realtime_ext".
context is optional: (switch => Realtime/@realtime_ext) and if left off, RealTime will use the current context, in this case "test".
family is also optional: (switch => Realtime/@) and if left off, RealTime will use the family name "extensions".
Currently there are no supported options so you can leave it off.
The family name above can be anything you wish. Just be sure it matches the family name you have stored in extconfig.conf: ( realtime_ext => mysql,asterisk,extensions_table )
And YES! You can have multiple switches and multiple family names using this method.
Database Table
Now lets create the table we need:NOTE: You can use any table name you wish, just make sure the table name matches what you have the above family name bound to.
#
# Table structure for table `extensions_table`
#
CREATE TABLE `extensions_table` (
`id` int(11) NOT NULL auto_increment,
`context` varchar(20) NOT NULL default '',
`exten` varchar(20) NOT NULL default '',
`priority` tinyint(4) NOT NULL default '0',
`app` varchar(20) NOT NULL default '',
`appdata` varchar(128) NOT NULL default '',
PRIMARY KEY (`context`,`exten`,`priority`),
KEY `id` (`id`)
) TYPE=MyISAM;
#
# Dumping data for table `extensions_table`
#
INSERT INTO `extensions_table` VALUES (1, 'mycontext', '_574555XXXX', 1, 'Wait', '2');
INSERT INTO `extensions_table` VALUES (2, 'mycontext', '_574555XXXX', 2, 'SayNumber', '102');
INSERT INTO `extensions_table` VALUES (3, 'mycontext', '2815551212', 1, 'Playback', 'pbx-invalid');
Matthen Boehm writes:
Here are some "complicated" extensions that work in my RealTime extensions:
INSERT INTO `extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (5, 'cytel', '8322008630', '1', 'Dial', 'SIP/3044,30');
INSERT INTO `extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (7, 'cytel', '80', '1', 'Voicemailmain', '@cytel');
INSERT INTO `extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (8, 'cytel', '_832.', '1', 'Dial', 'SIP/${EXTEN}@66.88.74.85|30');
INSERT INTO `extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (9, 'cytel', '_9X.', '1', 'Dial',
'IAX2/devasterisk:asterisk@asterisk-alpha/${EXTEN}@cytel-internal');
INSERT INTO `extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (10, 'cytel', '3013', '1', 'Dial', 'SIP/3013|30');
INSERT INTO `extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (11, 'cytel', '_3XXX', '1', 'Dial',
'IAX2/devasterisk:asterisk@asterisk-alpha/${EXTEN}@cytel-internal');
Caveats
Although Asterisk can handle pattern extension names in a realtime DB, there is something you ought to know. They can severely slow down Asterisk.
Why?
Because Asterisk will first attempt to do a direct match db lookup first for any lookup by extension. If it succeeds, all is well. But if it does not succeed, then it will sequentially load every extension in the context, and sequentially test to see which best matches the input number. If you have a small number of extensions, this is usually not a big deal. But if you have hundreds or thousands of extensions, finding the best match could take several seconds!
So, as a rule of thumb, do not put extension patterns in your realtime database. In 1.6, there is code added to the core pbx to use a trie-based search that makes the pattern search time almost constant, no matter how many patterns. But this is not possible in a realtime database situation. It must continue to use the old technique which involves testing all patterns in a context to find the 'best' match, which grows exponentially slower with the number of patterns. If you absolutely must use patterns, keep them in the in-memory dialplan (extensions.ael, extensions.conf). Let the DB do the exact matches in large datasets that it is built for.
One more thing: It is usually wise to separate program from data. Keep the logical control dialplan stuff in extensions.ael and extensions.conf, and reserve realtime lookups for true database lookups. Keep extensions.conf and extensions.ael in some sort of source-control system, like cvs, subversion, or git, so you can track your changes and have some backup. Just because you CAN store your dialplan in a database, doesn't mean it would be practical, expedient, or right to do so.
Testing
Now place a call into the [test] context. Asterisk should query the associated database/table for the number you dialed.
So if you dial 5745558896, you should Wait(2), then hear Allison saying the numbers "one zero two".
If you dial 2815551212 you would hear Allison saying "I'm sorry. That's not a valid extension"
The 'i' and 's' extensions are currently not supported. The 't' extension is supported.
Edit: Latest CVS will accept 'i' and 's' / rowitech
Note on using Goto and GotoIf in the extensions table (and DIAL!)
When using a Goto or GotoIf or Dial command you may only use '|' in the app_data field of the command and not ','. For example, the app_data field must take the form of context|s|1 and not context,s,1. Or if using dial, it should be SIP/user|60|Tt, not SIP/user,60,Tt.
Cheers,
Matthew... and now Phil too.
UPDATE
inserting extensions using id values in the examples doesn't make any real sense on an autoincrement primary key field
INSERT INTO `extensions_table` VALUES (1, 'mycontext', '_574555XXXX', 1, 'Wait', '2');
would be better inserted as:
INSERT INTO `extensions_table` VALUES (NULL, 'mycontext', '_574555XXXX', 1, 'Wait', '2'); etc
Cheers
inserting extensions using id values in the examples doesn't make any real sense on an autoincrement primary key field
INSERT INTO `extensions_table` VALUES (1, 'mycontext', '_574555XXXX', 1, 'Wait', '2');
would be better inserted as:
INSERT INTO `extensions_table` VALUES (NULL, 'mycontext', '_574555XXXX', 1, 'Wait', '2'); etc
Cheers
Page Changes
asterisk realtime pattern matching problem
Regards
Why include the "switch" command in a context
In all the cases I have seen, the switch command has to be included in a selected context.
I don't really understand why I can't use the realtime feature for all the contexts as the contextname is included in the database.
So, everytime I create a new context for a group of users, I have to modify my extensions.conf.
Why isn't there something like following ?
allcontexts
switch => Realtime/@
Sorry for my bad english, I hope someone could understand me.
Only ONE context in a RealTime Extensions ???
Thanks for this great post ^^
When I add an other context in my extensions table (ODBC/MySQL), the new extens add in this new context doesn't work !
If I use only one context for every extens, all work fine !
Do somebody have the same problem ??
Please help me ! Thanks for any help.
My extconfig.conf :
extensions => odbc,asterisk,extensions
My extensions.conf :
[interne]
switch => Realtime/interne@extensions
[outgoing]
switch => Realtime/outgoing@extensions
handling T and t extensions
My solution was to add the keyword "binary" into the query statements in the RealTime mysql source ( res_config_mysql.c )
snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE BINARY %s%s '%s'", table, newparam, op, buf);<<<<<<
whilenewparam = va_arg(ap, const char *) {
newval = va_arg(ap, const char *);
if(!strchr(newparam, ' ')) op = " ="; else op = "";
if valsz = strlen (newval * 2 + 1 > sizeof(buf))
valsz = (sizeof(buf) - 1) / 2;
mysql_real_escape_string(&mysql, buf, newval, valsz);
snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND BINARY %s%s '%s'", newparam, op, buf);<<<<<<<<<
}
This segment of code occurs in TWO PLACES, so I changed them both. Once you change the source of course you have to do a "make" and then copy the res_config_mysql.so to wherever your asterisk modules live ( mine are in "/usr/lib/asterisk/modules" ).
Now the dial plan using MySQL realtime works fine for 't' and 'T'. ***NOTE Of course this could have side effects since now ALL queries will be case-sensitive and won't tolerate ( for instance ) spaces on either side of the string. There is also apparently a way to make MySQL case-sensitive using the collation settings but this seemed more straight forward.
Ex-Girlfriend option not working
exten => _0X./200, 1, Dial(SIP/${EXTEN}@sipout-200)
exten => _0X./300, 1, Dial(SIP/${EXTEN}@sipout-300)
...
Using extensions.conf, this will work fine, a different SIP channel will be used depending on the Caller ID: sipout-200 when $CALLERID(num) is set to 200 and sipout-300 when $CALLERID(num)=300. Using ARA and the MySQL native driver, Asterisk uses always sipout-200, no matter what value $CALLERID(num) is set to.
The "Ex-Girlfriend option" is not only used to block some numbers, it's a very good feature to select different channels depending on the Caller ID. What a bad luck it's not working in ARA!
include in RealTime Extensions
Include context
How we can include context in our realtime configuration? How to add inlude=>local to include local context in distance call context? Is there any way to put that line in our extension table?
BR
Zdravko
The S Extension
when using mysql Realtime. ive tried everything it works fine using exten
numbers, but when adding in "s" "i" i get not found.
im testing a simple dial plan in the extensions table
135 incoming s 1 Answer
136 incoming s 2 Playback hello-world
137 incoming s 3 Hangup
thats pretty much it, when i change the s extension to say 600
i get hello world.
any one know why the s extension doesnt work for me ive tried everything
Alan
Re: hint priority
I don't know if this would work but try setting priority to -1. And see if it works.
I'd be interested in what you achieve.
Greetings, Philipp
hint priority