Asterisk RealTime Extensions

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

(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.

NOTE: It seems like Asterisk 1.6.0 always matches the realtime context with the name of the static context that contains the switch statement. The above example will always seek for the "Test" context in the database and not for the "mycontext". So you might as well use:


[test]
switch => Realtime



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.

NOTE: You should REALLY add indices for the context, exten and priority columns, as your asterisk system might slow down considerably otherwise.


#
# Table structure for table `bit_extensions_table`
#

CREATE TABLE `bit_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 `bit_extensions_table`
#

INSERT INTO `bit_extensions_table` VALUES (1, 'mycontext', '_574555XXXX', 1, 'Wait', '2');
INSERT INTO `bit_extensions_table` VALUES (2, 'mycontext', '_574555XXXX', 2, 'SayNumber', '102');
INSERT INTO `bit_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 `bit_extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (5, 'cytel', '8322008630', '1', 'Dial', 'SIP/3044,30');

INSERT INTO `bit_extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (7, 'cytel', '80', '1', 'Voicemailmain', '@cytel');

INSERT INTO `bit_extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (8, 'cytel', '_832.', '1', 'Dial', 'SIP/${EXTEN}@66.88.74.85|30');

INSERT INTO `bit_extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (9, 'cytel', '_9X.', '1', 'Dial',
'IAX2/devasterisk:asterisk@asterisk-alpha/${EXTEN}@cytel-internal');

INSERT INTO `bit_extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (10, 'cytel', '3013', '1', 'Dial', 'SIP/3013|30');

INSERT INTO `bit_extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (11, 'cytel', '_3XXX', '1', 'Dial',
'IAX2/devasterisk:asterisk@asterisk-alpha/${EXTEN}@cytel-internal');




PHP Script to import extensions.conf into realtime MySQL table:


RZero Writes :

If you want to import your current extension.conf to be used in realtime with this set up use this php script http://pastebin.com/SqNRJdbD
It parses the extension.conf and inserts the data in the correct order with the priority set correctly when using `n` as well as contexts also it will run a check to ensure that you don't have any duplicated entries before inserting the data if you are importing from more than one server. Don't forget to make your script executable !
Ps sorry to having to use the pastebin its because of the the script looks messed up when pasted into here.

imcdona Writes:

I've attached the RZero's PHP script here
import-extensions.php.txt
I left the link to pastebin in case the attachment get's deleted which has happened in the past.



When calling a macro from the extensions_conf database you need to pipe delimit your appdata where asterisk doesn't convert the commas to pipes when it parses the data. So an example of an extensions_conf insert statement for a Macro entry would look like:
Insert into extensions_conf (context,exten,priority,app,appdata) values ('internal','1234','1','Macro','ExtensionDial|1234|SIP/1234@gateway');

In the database it would look like the following:

context exten priority app appdata
internal 1234 1 Macro ExtensionDial|1234|SIP/1234@gateway

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.

There is a patch which adds an option to the Realtime switch which disables the search for extension pattern in the database: http://bugs.digium.com/view.php?id=13698

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 `bit_extensions_table` VALUES (1, 'mycontext', '_574555XXXX', 1, 'Wait', '2');
would be better inserted as:
INSERT INTO `bit_extensions_table` VALUES (NULL, 'mycontext', '_574555XXXX', 1, 'Wait', '2'); etc
Cheers


See Also

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

(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.

NOTE: It seems like Asterisk 1.6.0 always matches the realtime context with the name of the static context that contains the switch statement. The above example will always seek for the "Test" context in the database and not for the "mycontext". So you might as well use:


[test]
switch => Realtime



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.

NOTE: You should REALLY add indices for the context, exten and priority columns, as your asterisk system might slow down considerably otherwise.


#
# Table structure for table `bit_extensions_table`
#

CREATE TABLE `bit_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 `bit_extensions_table`
#

INSERT INTO `bit_extensions_table` VALUES (1, 'mycontext', '_574555XXXX', 1, 'Wait', '2');
INSERT INTO `bit_extensions_table` VALUES (2, 'mycontext', '_574555XXXX', 2, 'SayNumber', '102');
INSERT INTO `bit_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 `bit_extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (5, 'cytel', '8322008630', '1', 'Dial', 'SIP/3044,30');

INSERT INTO `bit_extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (7, 'cytel', '80', '1', 'Voicemailmain', '@cytel');

INSERT INTO `bit_extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (8, 'cytel', '_832.', '1', 'Dial', 'SIP/${EXTEN}@66.88.74.85|30');

INSERT INTO `bit_extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (9, 'cytel', '_9X.', '1', 'Dial',
'IAX2/devasterisk:asterisk@asterisk-alpha/${EXTEN}@cytel-internal');

INSERT INTO `bit_extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (10, 'cytel', '3013', '1', 'Dial', 'SIP/3013|30');

INSERT INTO `bit_extensions` (`id`, `context`, `exten`, `priority`, `app`, `appdata`)
VALUES (11, 'cytel', '_3XXX', '1', 'Dial',
'IAX2/devasterisk:asterisk@asterisk-alpha/${EXTEN}@cytel-internal');




PHP Script to import extensions.conf into realtime MySQL table:


RZero Writes :

If you want to import your current extension.conf to be used in realtime with this set up use this php script http://pastebin.com/SqNRJdbD
It parses the extension.conf and inserts the data in the correct order with the priority set correctly when using `n` as well as contexts also it will run a check to ensure that you don't have any duplicated entries before inserting the data if you are importing from more than one server. Don't forget to make your script executable !
Ps sorry to having to use the pastebin its because of the the script looks messed up when pasted into here.

imcdona Writes:

I've attached the RZero's PHP script here
import-extensions.php.txt
I left the link to pastebin in case the attachment get's deleted which has happened in the past.



When calling a macro from the extensions_conf database you need to pipe delimit your appdata where asterisk doesn't convert the commas to pipes when it parses the data. So an example of an extensions_conf insert statement for a Macro entry would look like:
Insert into extensions_conf (context,exten,priority,app,appdata) values ('internal','1234','1','Macro','ExtensionDial|1234|SIP/1234@gateway');

In the database it would look like the following:

context exten priority app appdata
internal 1234 1 Macro ExtensionDial|1234|SIP/1234@gateway

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.

There is a patch which adds an option to the Realtime switch which disables the search for extension pattern in the database: http://bugs.digium.com/view.php?id=13698

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 `bit_extensions_table` VALUES (1, 'mycontext', '_574555XXXX', 1, 'Wait', '2');
would be better inserted as:
INSERT INTO `bit_extensions_table` VALUES (NULL, 'mycontext', '_574555XXXX', 1, 'Wait', '2'); etc
Cheers


See Also

Created by: utdrmac, Last modification: Tue 25 of Nov, 2014 (22:03 UTC) by imcdona
Please update this page with new information, just login and click on the "Edit" or "Discussion" tab. Get a free login here: Register Thanks! - Find us on Google+