The Asterisk Realtime Architecture (ARA) enables you to
store the configuration files (that would normally be found in /etc/asterisk
) and their configuration options
in a database table. There are two types of realtime:
static and dynamic.
The static version is similar to the traditional method of reading a configuration file, except that the data is read from the database instead.
The dynamic realtime method, which loads and updates the information as it is required, is used for things such as SIP/IAX2 user and peer objects and voicemail.
Making changes to static information requires
a reload, just as if you had changed a text file on the system, but
dynamic information is polled by Asterisk as needed, so no reload is
required when changes are made to this data. Realtime is configured in the
extconfig.conf
file located in the
/etc/asterisk
directory. This file
tells Asterisk what to load from the database and where to load it from,
allowing certain files to be loaded from the database and other files to
be loaded from the standard configuration files.
Static realtime is useful when you want to load from a
database the configuration that you would normally place in the
configuration files in /etc/asterisk
. The same rules that apply to
flat files on your system still apply when using static realtime. For
example, after making changes to the configuration you must either run
the reload command from the Asterisk CLI, or reload the module associated
with the configuration file (e.g., using module reload chan_sip.so
).
When using static realtime, we tell
Asterisk which files we want to load from the database using the
following syntax in the extconfig.conf
file:
; /etc/asterisk/extconfig.conf filename.conf => driver,database[,table]
If the table name is not specified, Asterisk will use the name of the file as the table name instead.
The static realtime module uses a specifically formatted table to read the configuration of static files in from the database. Table 16.2, “Table layout and description of ast_config” illustrates the columns as they should be defined in your database:
Table 16.2. Table layout and description of ast_config
A simple file we can load from static
realtime is the musiconhold.conf
[149] file. Let’s start by moving this file to a temporary
location:
$
cd /etc/asterisk
$
mv musiconhold.conf musiconhold.conf.old
In order for the classes to be removed from memory, we need to restart Asterisk. Then we can verify that our classes are blank by running moh show classes:
*CLI>
core restart now
*CLI>
moh show classes
*CLI>
Let’s put the [default]
class back into Asterisk, but now
we’ll load it from the database. Connect to your database and execute
the following INSERT
statements:
>INSERT INTO ast_config (filename,category,var_name,var_val) VALUES ('musiconhold.conf','default','mode','files');
>INSERT INTO ast_config (filename,category,var_name,var_val) VALUES ('musiconhold.conf','default','directory','/var/lib/asterisk/moh');
You
can verify that your values have made it into the database by running a
SELECT
statement:
asterisk=#
SELECT filename,category,var_name,var_val FROM ast_config;
filename | category | var_name | var_val ------------------+----------------+--------------+------------------------ musiconhold.conf | default | mode | files musiconhold.conf | default | directory | /var/lib/asterisk/moh (2 rows)
There’s one last thing to modify in the
extconfig.conf
file in the
/etc/asterisk
directory to tell
Asterisk to get the data for musiconhold.conf
from the database using the
ODBC connection. The first column states that we’re using the ODBC
drivers to connect (res_odbc.conf
)
and that the connection name is asterisk
(as defined with [asterisk]
in res_odbc.conf
). Add the following line to the
end of the extconfig.conf
file, and
then save it:
musiconhold.conf => odbc,asterisk,ast_config
Then connect to the Asterisk console and perform a reload:
*CLI>
module reload res_musiconhold.so
You can now verify that your music on hold classes are loading from the database by running moh show classes:
*CLI>
moh show classes
Class: general Mode: files Directory: /var/lib/asterisk/moh
And there
you go: musiconhold.conf
loaded
from the database. If you have issues with the reload of the module
loading the data into memory, try restarting Asterisk. You can perform
the same steps in order to load other flat files from the database, as
needed.
The dynamic realtime system is used to load objects that may change often, such as SIP/IAX2 users and peers, queues and their members, and voicemail messages. Likewise, when new records are likely to be added on a regular basis, we can utilize the power of the database to let us load this information on an as-needed basis.
All of realtime is configured in the
/etc/asterisk/extconfig.conf
file, but dynamic realtime has well-defined configuration
names. Defining something like SIP peers is done with the following
format:
; extconfig.conf sippeers =>driver
,database
[,table
]
The
table name is optional. If it is omitted, Asterisk will use the
predefined name (i.e., sippeers
) to
identify the table in which to look up the data.
Remember that we have both SIP peers and SIP users: peers are end-points we send calls to, and a user is something we receive calls from. A friend is shorthand that defines both.
In our example, we’ll be using the ast_sippeers
table to store our SIP peer
information. So, to configure Asterisk to load all SIP peers from our
database using realtime, we would define something like this:
; extconfig.conf sippeers => odbc,asterisk,ast_sipfriends
To also load our
SIP users from the database, we would define the sipusers
object like so:
sipusers => odbc,asterisk,ast_sipfriends
You
may have noticed we used the same table for both the sippeers
and sipusers
. This is because there will be a
type
field (just as if we were
defining the type in the sip.conf file) that will
let us define a type of user
,
peer
, or friend
. If you unload chan_sip.so
and then load it back into memory
(i.e., using module unload
chan_sip.so followed by module load
chan_sip.so) after configuring extconfig.conf
, you will be greeted with some
warnings telling you which columns you’re missing for the realtime
table. Since we’ve enabled sippeers
and sipusers
in extconfig.conf
, we will get the following on
the console (which has been trimmed due to space requirements):
WARNING: Realtime table ast_sipfriends@asterisk requires column 'name', but that column does not exist! WARNING: Realtime table ast_sipfriends@asterisk requires column 'ipaddr', but that column does not exist! WARNING: Realtime table ast_sipfriends@asterisk requires column 'port', but that column does not exist! WARNING: Realtime table ast_sipfriends@asterisk requires column 'regseconds', but that column does not exist! WARNING: Realtime table ast_sipfriends@asterisk requires column 'defaultuser', but that column does not exist! WARNING: Realtime table ast_sipfriends@asterisk requires column 'fullcontact', but that column does not exist! WARNING: Realtime table ast_sipfriends@asterisk requires column 'regserver', but that column does not exist! WARNING: Realtime table ast_sipfriends@asterisk requires column 'useragent', but that column does not exist! WARNING: Realtime table ast_sipfriends@asterisk requires column 'lastms', but that column does not exist!
As you can see, we are missing several columns from the table
ast_sipfriends
, which we’ve defined
as connecting to the asterisk
object
as defined in res_odbc.conf
. The
next step is to create our ast_sipfriends
table with all the columns
listed by the warning messages, in addition to the following: the
type
column, which is required to
define users, peers, and friends; the secret
column, which is used for setting a
password; and the host
column, which
allows us to define whether the peer is dynamically registering to us or
has a static IP address. Table 16.3, “Minimal sippeers/sipusers realtime table” lists all
of the columns that should appear in our table, and their types.
Table 16.3. Minimal sippeers/sipusers realtime table
Column name | Column type |
---|---|
type | Varchar 6 |
name | Varchar 128 |
secret | Varchar 128 |
context | Varchar 128 |
host | Varchar 128 |
ipaddr | Varchar 128 |
port | Varchar 5 |
regseconds | Bigint |
defaultuser | Varchar 128 |
fullcontact | Varchar 128 |
regserver | Varchar 128 |
useragent | Varchar 128 |
lastms | Integer |
For each peer you want to register, you
need to insert data in the columns type
, name
,
secret
, context
, host
, and defaultuser
. The rest of the columns will be
populated automatically when the peer registers.
The port
, regseconds
, and ipaddr
fields are required to let Asterisk
store the registration information for the peer so it can determine
where to send the calls. (Note that if the peer is static
, you will have to populate the ipaddr
field yourself.) The port
field is optional and defaults to the
standard port defined in the [general]
section, and the regseconds
will remain blank. Table 16.4, “Example information used to populate the ast_sipfriends
table” lists some sample values that we’ll use
to populate our ast_sipfriends
table.
Table 16.4. Example information used to populate the ast_sipfriends table
Column name | Value |
---|---|
type | friend |
name | 0000FFFF0008 |
defaultuser | 0000FFFF0008 |
host | dynamic |
secret | welcome |
context | LocalSets |
Prior to registering your peer, though, you
need to enable realtime caching in sip.conf
. Otherwise, the peer will not be
loaded into memory, and the registration will not be remembered. If your
peers only place calls and don’t need to register to your system, you
don’t need to enable realtime caching because the peers will be checked
against the database each time they place a call. However, if you load
your peers into memory, the database will only need to be contacted on
initial registration, and after the registration expires.
Additional options in sip.conf
exist for realtime peers. These are defined in the
[general]
section and described in Table 16.5, “Realtime options in sip.conf”.
Table 16.5. Realtime options in sip.conf
Configuration option | Description |
---|---|
rtcachefriends | Caches peers in memory on an as-needed basis after
they have contacted the server. That is, on Asterisk start, the
peers are not loaded into memory automatically; only after a
peer has contacted the server (e.g., via a registration or phone
call) is it loaded in memory. Values are yes or no . |
rtsavesysname | When a peer registers to the system, saves the
systemname (as defined in
asterisk.conf ) into the
regserver field within the
database. (See Setting the systemname for Globally Unique IDs for more
information.) Using regserver
is useful when you have multiple servers registering peers to
the same table. Values are yes or no . |
rtupdate | Sends registration information such as the IP
address, the origination port, the registration period, and the
username of the user-agent to
the database when a peer registers to Asterisk. Values are
yes or no , and the default is yes . |
rtautoclear | Automatically expires friends on the same schedule
as if they had just registered. This causes a peer to be removed
from memory when the registration period has expired, until that
peer is requested again (e.g., via registration or placing a
call). Values are yes ,
no , or an integer value that
causes the peers to be removed from memory after that number of
seconds instead of the registration interval. |
ignoreregexpire | When enabled, peers are not removed from memory when the registration period expires. Instead, the information is left in memory so that if a call is requested to an endpoint that has an expired registration, the last known information (IP address, port, etc.) will be tried. |
After enabling rtcachefriends=yes
in sip.conf
and reloading chan_sip.so
(using module reload chan_sip.so), you can register
your peer to Asterisk using realtime, and the peer should then be
populated into memory. You will be able to verify this by executing the
sip show peers command on the
Asterisk console:
Name/username Host Dyn Port Status Realtime 0000FFFF0008/0000FFFF0008 172.16.0.160 D 5060 Unmonitored Cached RT
If you were to look at the table in the database directly, you would see something like this:
+--------+--------------+---------+-----------+---------+--------------+ | type | name | secret | context | host | ipaddr | +--------+--------------+---------+-----------+---------+--------------+ | friend | 0000FFFF0008 | welcome | LocalSets | dynamic | 172.16.0.160 | +--------+--------------+---------+-----------+---------+--------------+ +------+------------+--------------+-------------------------------------+ | port | regseconds | defaultuser | fullcontact | +------+------------+--------------+-------------------------------------+ | 5060 | 1283928895 | 0000FFFF0008 | sip:0000FFFF0008@172.16.0.160:52722 | +------+------------+--------------+-------------------------------------+ +-----------+-----------------+--------+ | regserver | useragent | lastms | +-----------+-----------------+--------+ | NULL | Zoiper rev.6739 | 0 | +-----------+-----------------+--------+
There are many more options
for that we can define for SIP friends, such as the caller ID; adding
that information is as simple as adding a callerid
column to the table. See the
sip.conf.sample
file for more options
that can be defined for SIP friends.
[149] The musiconhold.conf
file
can also be loaded via dynamic realtime, but we’re using it
statically as it’s a simple file that makes a good example.