25. Install Asterisk

by Double Bastion - Updated December 12, 2022

25.1. General considerations

VoIP (voice over IP) phones are of three types:

  • hardphones: these are hardware phones that look exactly like regular phones but they are connected through UTP cables and RJ45 jacks to routers/adapters and they use VoIP protocols to make and receive calls over the Internet.
  • softphones: these are software phones that act like hardphones. You have to install them first on your desktop/laptop/mobile phone before using them.
  • browser phones: these are softphones that load in a browser, like any web page.

The greatest advantage that browser phones offer is that you don’t need to install anything on your device (desktop/laptop/tablet/mobile phone). You can access and use a browser phone from any device that has a browser and is connected to the Internet, from anywhere in the world.

In general, browser phones use WebRTC, so you need to have WebRTC enabled in your browser. Browsers like Firefox, Opera, Vivaldi, Chrome, have WebRTC support and they have it enabled by default. However, if you disabled WebRTC in order to prevent DNS IP leaks when using a VPN, you will have to re-enable it, to be able to use browser phones. (Although we have mentioned Chrome here, we want to discourage its use. If you value freedom and privacy you won’t use Chrome).

Further ahead, in two different chapters, we will explain how to install two browser phones: ‘Roundpin’, and ‘SIP Trip Phone’, which is an application for Nextcloud. ‘SIP Trip Phone’ is an audio-only browser phone intended to be used as a backup for ‘Roundpin’, which supports both audio and video calls, as well as video conferences.

Both Roundpin and SIP Trip Phone can be used in conjunction with Asterisk, to benefit from the control, autonomy and advanced PBX features offered by Asterisk, or without Asterisk, by connecting them directly to SIP providers. In the latter case, a big part of the autonomy and control over your telephony system will be lost and every conversation will cost, while if you use Asterisk, all the conversations between Asterisk extensions, both audio and video, will be gratis. Also, Roundpin allows text messaging and video calls/conferences only when used in conjunction with Asterisk.

The best PBX (Private Branch Exchange) server is Asterisk. Asterisk is a free and open source PBX designed to switch calls, manage routes, connect callers with the outside world over IP, etc. With Asterisk installed on your server and ‘Roundpin’ and ‘SIP Trip Phone’ connected to it, you’ll be able to make phone calls over the Internet to other WebRTC clients. But what if you want to make phone calls from your browser phone to landline or mobile phone numbers ? For that you’ll need an interface between the Internet and the PSTN (Public Switched Telephony Network). Thus you’ll need a SIP account provider that allows you to use your SIP account to make phone calls to regular phone numbers. These SIP providers can also offer you a real phone number associated with your SIP account, and located in a geographic area of your choice; you can use that phone number to call and receive calls as if you were physically present in that location. This implies much lower costs than with classical landline phones or mobile phones, since most of the communication uses the infrastructure of the Internet. The price difference is even greater for international calls which will have prices similar to local calls. In this setup, your SIP account provider will act as a PSTN/SIP gateway, while your Asterisk server will act as a SIP/WebRTC gateway.

As we’ll describe in this chapter, you will connect your browser phone to your SIP provider via Asterisk. Experience shows that this is not only possible but really efficient, since Asterisk doesn’t burden the underlying server and it doesn’t generate any sound lag in phone conversations. Asterisks uses only about 68 MB of RAM memory in idle state and a bit more when phone calls pass through. In addition, Asterisk gives you endless possibilities to configure your telephony system according to the specifics of your use case. Thus, you can configure as many WebRTC clients as you like and have them dial each other, you can configure an IVR (Interactive Voice Response) or auto-attendant or voice menu, you can implement call queues, you can direct incoming calls to voicemail or to specific extensions, you can have voice messages sent to email addresses as attachments, you can implement call recording, audio/video conferences, black lists, etc.; you can do all these independently of your SIP provider. You only need an account and a real phone number from the SIP provider, to be able to interface with the PSTN; all the rest is done on your own server, including the IVR, the voicemail, the call recording, etc. This allows you to have total control over your communications and more privacy than if you were using the SIP provider’s voicemail, call recording, etc.

The setup explained below will allow you to make multiple concurrent outgoing calls and to receive multiple incoming concurrent calls, to/from any landline or mobile phone in the world, the only limitations being those imposed by the SIP provider and your Internet bandwidth. A regular voice phone conversation requires a bandwidth of about 64 kbps.

Somebody can ask if a web interface for configuring and managing Asterisk, like Free PBX, would be desirable. The answer is that in other scenarios Free PBX might be a good idea, but for the setup described in this guide it’s not. Using Free PBX adds another layer of complexity, another potential point of failure, uses another portion of the server’s CPU and RAM, etc. Why should you add an additional component to your setup since you can spare the CPU and RAM memory by configuring and using Asterisk directly ?

This chapter describes how to configure your Asterisk server in order to connect it to a Telnyx or Localphone account. You can use either of the two providers or both of them simultaneously. Both Telnyx and Localphone are recommended by their low prices and high sound quality and Double Bastion has no affiliation with them. It is assumed that you will also attach a real phone number to your Telnyx/Localphone account. We’ll explain below how to do it. (If, for whatever reason, you want to connect your Asterisk server to a Twilio, Flowroute or Vonage account, this page contains the necessary instructions.)

If you are not very familiar with terms like VoIP, PBX, SIP, SIP trunk, SIP channel, you can read this article.

25.2. Build and install Asterisk

The standard way to install Asterisk is to first compile it from source on the machine on which it will be installed, and then install it.

First update the system:

apt-get update
apt-get dist-upgrade

Next access the official Asterisk versions repository. The newest version of Asterisk that has been compiled and verified to function with Roundpin and SIP Trip Phone is 18.0.0 LTS (Long Term Support). To download Asterisk 18.0.0 LTS right-click on asterisk-18.0.0.tar.gz, choose ‘Copy Link’ to copy the download link to clipboard. Then, on your remote server navigate to /usr/src, download Asterisk, uncompress the archive, then remove it, as follows:

cd /usr/src
wget https://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-18.0.0.tar.gz
tar xf asterisk-18.0.0.tar.gz
rm asterisk-18.0.0.tar.gz

There is a limit for the maximum number of streams that can be served simultaneously during a video conference in ‘selective forwarding unit’ (sfu) mode. Currently this limit is hard-coded to 16. This means that in a video conference where each participant sees all the other participants, the maximum number of participants will be 15: one stream will be used for the audio track with the combined sound from all the participants, and the other 15 will be used for the 15 individual video streams. Since Asterisk is licensed under GNU Public License version 2, you have the right to change the source code of the program as you see fit. Thus, before building Asterisk, we recommend that you change the maximum number of simultaneous streams, so as to allow more than 15 participants in video conferences. Indeed, the hardware resources of the server and the Internet bandwidth will never allow an unlimited number of participants in video conferences, but it’s better to have no other limits imposed by the software. However, Asterisk has been designed with a defined maximum number of streams and this limit can’t be removed entirely. Therefore, you should increase it before compiling. To change the hard-coded limit of 16, first open the /usr/src/asterisk-18.0.0/third-party/pjproject/patches/config_site.h file for editing:

nano /usr/src/asterisk-18.0.0/third-party/pjproject/patches/config_site.h

Then search for the following string:

PJMEDIA_MAX_SDP_MEDIA

Change that line to make it look like this:

#define PJMEDIA_MAX_SDP_MEDIA   99

This will allow a maximum of 99 streams instead of 16. Please note that if you set a limit much higher than 99, your browser phone may get disconnected from Asterisk with a ‘websocket error’ message when you will try to make audio/video calls, as our tests proved.


Then, navigate to the /usr/src/asterisk-18.0.0 directory:

cd /usr/src/asterisk-18.0.0

You will have to install all the needed dependencies by running the install-prereq script like this:

contrib/scripts/install_prereq install

When you will see the following screen asking you to enter the country calling code:

just delete the default 61 code, leave the field empty, press Tab to select OK, then press Enter, because you won’t need to configure your country calling code here.

When all the dependencies will have been installed, you will see the message:

#############################################
## install completed successfully
#############################################

Then download the packages needed to build the mp3 module by running:

contrib/scripts/get_mp3_source.sh

Next, run the ./configure script which will check your system for missing libraries and binaries and prepare the Asterisk source code for the compilation process:

./configure

At the end of the process, a message similar with the following will be displayed:

configure: Menuselect build configuration successfully completed

               .$$$$$$$$$$$$$$$=..
            .$7$7..          .7$$7:.
          .$$:.                 ,$7.7
        .$7.     7$$$$           .$$77
     ..$$.       $$$$$            .$$$7
    ..7$   .?.   $$$$$   .?.       7$$$.
   $.$.   .$$$7. $$$$7 .7$$$.      .$$$.
 .777.   .$$$$$$77$$$77$$$$$7.      $$$,
 $$$~      .7$$$$$$$$$$$$$7.       .$$$.
.$$7          .7$$$$$$$7:          ?$$$.
$$$          ?7$$$$$$$$$$I        .$$$7
$$$       .7$$$$$$$$$$$$$$$$      :$$$.
$$$       $$$$$$7$$$$$$$$$$$$    .$$$.
$$$        $$$   7$$$7  .$$$    .$$$.
$$$$             $$$$7         .$$$.
7$$$7            7$$$$        7$$$
 $$$$$                        $$$
  $$$$7.                       $$  (TM)
   $$$$$$$.           .7$$$$$$  $$
     $$$$$$$$$$$$7$$$$$$$$$.$$$$$$
       $$$$$$$$$$$$$$$$.

configure: Package configured for:
configure: OS type  : linux-gnu
configure: Host CPU : x86_64
configure: build-cpu:vendor:os: x86_64 : pc : linux-gnu :
configure: host-cpu:vendor:os: x86_64 : pc : linux-gnu :

Next configure a few building options by running:

make menuselect

On the left panel select ‘Add-ons’, then use the right arrow key to go to the right panel, then use the down arrow key to select ‘format_mp3’, then press Enter to mark it as selected with an asterisk:

asterisk_installation_2

Next, use the left arrow key to go to the left panel, select ‘Core Sound Packages’, then on the right panel select ‘CORE-SOUNDS-EN-WAV’ (or a similar package for a different language than English, that you can find by scrolling down the list with the down arrow key), and press Enter to mark it as selected:

asterisk_installation_3

Next, select ‘Extras Sound Packages’ on the left panel, then on the right panel select ‘EXTRA-SOUNDS-EN-WAV’ (or a similar package for a different language than English) and press Enter to mark it as selected:

asterisk_installation_4

Then select ‘Save & Exit’ with the right arrow key, then press Enter.



Now you are ready to start the building process. If your server has more than 1 CPU core, you can take advantage of all the cores during the building process by specifying the number of cores, using the -j option. So, if you have 2 CPU cores, the command will be:

make -j2

If you have just one CPU core, run:

make

The duration of the building process will depend on the processing power of the server. On a 1 core CPU, 2 GB RAM VPS it will last about 10 minutes.

When the building process finishes, if it succeeds, you will see the following message:

 +--------- Asterisk Build Complete ---------+
 + Asterisk has successfully been built, and +
 + can be installed by running:              +
 +                                           +
 +                make install               +
 +-------------------------------------------+



If an old version of Asterisk is already running on your server and you are now upgrading Asterisk to the latest version, there is no need to uninstall the old version. Just stop your currently running Asterisk server:

systemctl stop asterisk

Then, follow the steps from below as for a regular installation.




Install the new Asterisk version with:

make install

After a successfull installation you will see the following message:

  +---- Asterisk Installation Complete -------+
 +                                           +
 +    YOU MUST READ THE SECURITY DOCUMENT    +
 +                                           +
 + Asterisk has successfully been installed. +
 + If you would like to install the sample   +
 + configuration files (overwriting any      +
 + existing config files), run:              +
 +                                           +
 + For generic reference documentation:      +
 +    make samples                           +
 +                                           +
 + For a sample basic PBX:                   +
 +    make basic-pbx                         +
 +                                           +
 +                                           +
 +-----------------  or ---------------------+
 +                                           +
 + You can go ahead and install the asterisk +
 + program documentation now or later run:   +
 +                                           +
 +               make progdocs               +
 +                                           +
 + **Note** This requires that you have      +
 + doxygen installed on your local system    +
 +-------------------------------------------+



If below the above message you see a warning similar to the following:

 WARNING WARNING WARNING
 Your Asterisk modules directory, located at
 /usr/lib/asterisk/modules
 contains modules that were not installed by this
 version of Asterisk. Please ensure that these
 modules are compatible with this version before
 attempting to run Asterisk.

    cdr_syslog.so
    format_jpeg.so
    app_macro.so
    chan_phone.so
 WARNING WARNING WARNING

this means that you have just installed Asterisk over an older version of Asterisk, and some of the modules of the old version, located in /usr/lib/asterisk/modules weren’t overwritten with the new corresponding modules, since the new version didn’t contain them. In this situation you should make a copy of the listed modules in a directory such as /srv/removed-asterisk-modules/old-version-18.0.0, then just delete the modules mentioned in the warning.




Next, run the following command to install the Asterisk sample configuration files:

make samples

Install the Asterisk service initialization script by running:

make config

This command will show no output.

Next, install the log rotation script by running:

make install-logrotate

Also it’s recommended to update the cache of dynamic libraries paths by running:

ldconfig

Start Asterisk:

systemctl start asterisk

Check if Asterisk is running with:

systemctl status asterisk

Enable the Asterisk service to start on system boot:

systemctl enable asterisk

After installation, to check the installed version, run:

asterisk -V

The output should be:

Asterisk 18.0.0

At this moment, Asterisk runs as root. To increase security, you will have to make it run as the user asterisk, belonging to the group asterisk. First create the group:

addgroup asterisk

Add the user asterisk to the asterisk group, as system user, without log in access, with /var/lib/asterisk (which already exists) as home directory:

adduser --system --home /var/lib/asterisk --no-create-home --ingroup asterisk --shell /bin/false asterisk

Then, edit the /etc/default/asterisk file:

nano /etc/default/asterisk

Uncomment the following two lines, to make them look like this:

AST_USER="asterisk"
AST_GROUP="asterisk"

Add the user asterisk to the dailout and audio groups:

adduser asterisk dialout
adduser asterisk audio

Next, change the ownership of all the Asterisk files and directories so that the user asterisk can access those files:

chown -R asterisk:asterisk /var/{lib,log,run,spool}/asterisk /usr/lib/asterisk /etc/asterisk

Also edit the /etc/logrotate.d/asterisk file:

nano /etc/logrotate.d/asterisk

Delete the original content and add the following content inside this file:

/var/log/asterisk/debug /var/log/asterisk/console /var/log/asterisk/full /var/log/asterisk/messages /var/log/asterisk/*log {
        missingok
        rotate 15
        compress
        delaycompress
        notifempty
        size 2M
        create 640 asterisk asterisk
        sharedscripts
        postrotate
              /usr/sbin/asterisk -rx 'logger reload' > /dev/null 2> /dev/null
        endscript
}

The parameters from above will ensure that the logs written by Asterisk will be owned by the asterisk user and group, that they will be rotated only after they reach 2M in size and not weekly, and that only 15 archives will be kept, instead of the default 52, which is by far too much.

Restart Asterisk:

systemctl restart asterisk

Create the /etc/asterisk/keys directory, where you will copy the SSL certificate and key of the domain on which the browser phone will be running (cloud.example.com) and change its ownership:

mkdir /etc/asterisk/keys
chown asterisk:asterisk /etc/asterisk/keys

Please note that since you want to connect two browser phones to Asterisk simultaneously, namely SIP Trip Phone and Roundpin, the SSL certificate for cloud.example.com obtained from Let’s Encrypt, should also be valid for roundpin.example.com. In the next chapter of this guide, where we explain how to install Nextcloud, we also describe how to obtain such a Let’s Encrypt certificate.

Now, create a script to automatically copy the SSL certificate and key of cloud.example.com from their default location, /etc/letsencrypt/live/cloud.example.com/ , to /etc/asterisk/keys . This is because Asterisk will refuse to read the certificate and key in their default location.

Navigate to /srv/scripts:

cd /srv/scripts

Create the script:

nano copy-asterisk-cert

Enter the following content inside this file:

#! /bin/bash
cp /etc/letsencrypt/live/cloud.example.com/cert.pem /etc/asterisk/keys/
cp /etc/letsencrypt/live/cloud.example.com/privkey.pem /etc/asterisk/keys/
chown asterisk:asterisk /etc/asterisk/keys/cert.pem /etc/asterisk/keys/privkey.pem
chmod 600 /etc/asterisk/keys/cert.pem /etc/asterisk/keys/privkey.pem

Replace example.com with the main domain hosted on your server. Change permissions for this script:

chmod 700 copy-asterisk-cert

Please note that you cannot run the script just yet, since you haven’t obtained the Let’s Encrypt SSL certificate for cloud.example.com. We explain how to obtain this certificate in the next chapter of this guide, Install Nextcloud, in the Obtain a Let’s Encrypt SSL certificate subchapter, where we also show how to run the script for the first time, to copy the two files to the /etc/asterisk/keys directory.

Set up a cron job:

crontab -e

Add the following lines, so as to copy the SSL certificate and key once a week, on Monday, at 3:25 AM:

# Copy the SSL certificate and key for cloud.example.com from /etc/letsencrypt/live/cloud.example.com to /etc/asterisk/keys every Monday at 3:35 AM
35 3 * * 1 /srv/scripts/copy-asterisk-cert > /dev/null 2>&1

Replace example.com with the main domain hosted on your server.

25.3. Change the default Asterisk port

By default, Asterisk will accept connections on port 5060, which will be the target of very frequent attacks. Although there are port scanners that can detect open ports, it’s a good practice, with proven efficiency, to change the traditional port 5060 to something different, like 5382 or other number more difficult to guess than 5070 or 5061 which are very common targets of fraudulent registration attacks. So, choose carefully. Let’s say you’ve chosen 5827. You’ll have to edit the /etc/asterisk/pjsip.conf file. First make a copy of the original file:

cp /etc/asterisk/pjsip.conf /etc/asterisk/pjsip.conf_orig

Open the /etc/asterisk/pjsip.conf file for editing:

nano /etc/asterisk/pjsip.conf

Add the following lines at the bottom of the file:

[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0:5827

[transport-wss]
type=transport
protocol=wss
bind=0.0.0.0:5827

You have to open the non-standard Asterisk port in the firewall. You also need to open ports 8088, 8089 for the transport over WebSocket to work, and the range of ports from 10000 to 20000 over UDP, as RTP ports. To achieve this, first run:

ufw allow 5827

Replace 5827 with your custom port for Asterisk connections. Then run:

ufw allow 10000:20000/udp
ufw allow 8088
ufw allow 8089

25.4. RTP ports

Also you have to check that the right range of RTP ports is set in the rtp.conf file:

nano /etc/asterisk/rtp.conf

Under [general] you should have these two lines:

rtpstart=10000
rtpend=20000

25.5. Disable unused modules

By default, Asterisk will load a few modules that you don’t actually need. They will cause many errors if they are not configured, so it’s better to disable them so that Asterisk won’t try to load them when it starts.

Make a copy of the original /etc/asterisk/modules.conf file:

cp /etc/asterisk/modules.conf /etc/asterisk/modules.conf_orig

Open the file for editing:

nano /etc/asterisk/modules.conf

Add the following lines at the end of this file to disable the unnecessary modules:

noload => chan_oss.so
noload => res_config_ldap
noload => res_config_pgsql
noload => cel_pgsql
noload => cdr_pgsql
noload => cel_tds
noload => cel_sqlite3_custom
noload => cdr_sqlite3_custom
noload => cdr_tds
noload => res_phoneprov
noload => res_pjsip_phoneprov_provider
noload => cel_radius
noload => cdr_radius

25.6. Edit the /etc/asterisk/http.conf file

Then make a copy of the /etc/asterisk/http.conf file:

cp /etc/asterisk/http.conf /etc/asterisk/http.conf_orig

Open the file:

nano /etc/asterisk/http.conf

Below [general] add the following lines:

enabled=yes

bindaddr=123.123.123.123

bindport=8088

tlsenable=yes
tlsbindaddr=123.123.123.123:8089

tlscertfile=/etc/asterisk/keys/cert.pem
tlsprivatekey=/etc/asterisk/keys/privkey.pem

Replace 123.123.123.123 with the public IP address of your server.

Restart Asterisk:

systemctl restart asterisk

25.7. Acquire a real phone number from Telnyx and configure a Telnyx account

You can open a new Telnyx account by accessing https://telnyx.com/sign-up . You will need to buy at least one real phone number from Telnyx, to be able to use your Telnyx account in conjunction with Asterisk as described below. After a one time setup fee of $1, a US real phone number will cost $1 per month and you can make calls within the US starting from $0.0050 per minute and receive calls with $0.0075 per minute or less. Prices for phone numbers and per minute of phone conversation differ from country to country. You can find the list of prices here.

After you sign up for a Telnyx account, the first thing to do is to click on the ‘My Account’ icon in the upper right corner of the screen, then click on ‘My Account’, click on the ‘Account Level’ tab and then take the steps to undergo verification, to become ‘Level 1’ and ‘Level 2’ verified. ‘Level 1’ verification usually requires verifying the email address you used to create your Telnyx account, by clicking a link included in a message sent to that email address. ‘Level 2’ verification can be requested by pressing the ‘Verify’ button in the ‘Level 2 Verification’ section (on the ‘Verifications’ tab). After you make your request for ‘Level 2’ verification, a representative from Telnyx will look at your account details and (s)he may send you an email asking about the way you plan to use your Telnyx account, after which (s)he will approve the ‘Level 2’ verification. Being ‘Level 1’ and ‘Level 2’ verified unlocks all the features of a Telnyx account: you can buy numbers, assign a connection/messaging profile to a number, set up global messaging capabilities, create a multi-user organization, make international calls, set up call forwarding, send SMS messages at a higher rate.

While logged in to your telnyx.com account, click on ‘Numbers’, then on ‘My Numbers’ on the left panel. To buy a real phone number located in a country of your choice click on the ‘Search & Buy Numbers’ tab, then under ‘Local Numbers’, in the ‘Search Type’ select ‘Region’, in the ‘Region’ text field enter the name of the country, in the ‘Number Features’ select ‘Voice’, then, if you want your number to have other capabilities select other features such as ‘SMS’ from the drop-down list, then click on the ‘Search Numbers’ button. You will see a list with all the numbers available in the selected region. Choose the number that you like, click ‘Add to Cart’, then click on ‘Cart’ on the upper bar, then click on the ‘Place Order’ button.

After you have bought a local phone number click on ‘Numbers’, then on ‘My Numbers’ on the left panel; on the ‘My Numbers’ tab you will see your number in the list of acquired phone numbers.

Then click on ‘Voice’, ‘SIP Trunking’ on the left panel, click on the ‘Add SIP Connection’ button, in the ‘Name’ field enter the name of the new SIP connection, Asterisk_Server, then click on ‘Create SIP Connection’. After you create the new connection click on the small pencil icon to open the options window. On the options window, on the ‘BASIC’ tab, under ‘SIP Connection Type’ choose ‘Credentials’, then in the ‘Username’ field enter a username for this connection, asterisktelnyx for example, in the ‘Password’ field enter a strong password; write down the username and password to use them later, when configuring Asterisk. Next, under ‘AnchorSite’ choose a town that is closer to the physical location of your server, then click on the ‘Save All Changes’ button.

To be able to make phone calls you will also need to configure an ‘Outbound Voice Profile’. On the left panel click on ‘Voice’, ‘Outbound Voice Profiles’, then click on the ‘Add New Profile’ button. In the ‘Name’ field enter a name for the profile, 1_outbound for example, then click ‘Create’. In the new window, under ‘Associated Connections and Applications’ click ‘Add connections/apps to profile’, select the name of the SIP connection created earlier, Asterisk_Server, by checking its checkbox, then click ‘Add Connections/Apps to profile’. Next, under ‘Traffic Type’ choose ‘Conversational’, then under ‘International Allowed Destinations’ select the countries and regions to which outbound calls will be allowed, by clicking their name. You can select all the 253 countries and regions, to allow outbound calls to all of them. Click on ‘Save’ to save the changes.

Next, create a ‘Billing Group’. Click on the ‘My Account’ icon in the upper right corner of the screen, then on ‘Billing Overview’, then click on the ‘Billing Groups’ tab. In the ‘Create Billing Group’ field enter a name, Default_Billing for example, then click on ‘Create’. Then add the billing group to your phone number: click on ‘Numbers’, ‘My Numbers’ on the left panel, then on your number’s row, in the ‘Billing Group’ field select the billing group that you have just created, Default_Billing in our example. Also, in the ‘Connection or App’ field on the same row, choose the connection created earlier, Asterisk_Server in our example.

Please note that Telnyx charges both for outbound calls and for inbound calls. The price per minute varies depending on the distance and is detailed here.

Please also note that if you want to be able to call emergency services from your Telnyx number, you will have to explicitly enable emergency services for that phone number like this: while logged in to your Telnyx account click on ‘Numbers’, ‘My Numbers’ on the left panel, then on the row of the phone number for which you want to enable calling to emergency services click on the ‘Advanced’ wheel, then on the ‘Emergency’ tab check the ‘Emergency services enabled’ checkbox; then read the ‘Terms and Conditions’ and if you agree click on ‘Save Changes’. Next, you will be asked to enter the physical address that you want to associate with your phone number, so that it will be used when calling emergency services. If you enable and use emergency services, you will be charged an additional fee per month, for each number for which you enable emergency services. For an American phone number, the emergency service is called e911 which stands for ‘Enhanced 911’ and means that when you call 911, along with the call, some other data is transmitted as metadata, such as your physical address. For an American number, the monthly fee that is added when enabling emergency services is $1.50.

It’s good to know that if you enable SMS messaging for a Telnyx number by associating a ‘Messaging Profile’ with that number, a monthly recurring charge (MRC) will be added for that number. For an American phone number, the additional charge is $0.10 per number, per month.

25.7.1. Number of concurrent inbound/outbound calls when using Telnyx

By default, a Telnyx account with billing configured as ‘Pay per minute’ and not ‘Pay per channel’ (to change the billing method you can click on the ‘Advanced’ wheel on the number’s row, then on the ‘Advanced’ tab, under ‘Voice Billing Method’, choose the billing method) allows:

– an unlimited number of concurrent (simultaneous) inbound calls to each real phone number acquired from Telnyx. The only limit to the number of concurrent inbound calls will be your Internet bandwidth, taking into account that a regular voice phone conversation requires a bandwidth of about 64 kbps.

– 10 concurrent (simultaneous) outbound calls from your account (from all your phone numbers combined). This number can be increased if needed, by making a request to Telnyx’s technical support.

25.8. Acquire a real phone number from Localphone and configure a Localphone account

You can open a new Localphone account at https://www.localphone.com/register . You will need to buy at least one real phone number from Localphone, to be able to use your Localphone account in conjunction with Asterisk as described below. After a one time setup fee of $3.60, a US real phone number will cost $0.88 per month and you can make calls within the US starting from $0.006 per minute. Incoming calls are free. Prices differ from country to country. You can find the list of prices for phone numbers here and the list of prices for phone calls here.

After you sign up, log in to your localphone.com account and click on the ‘Internet Phone’ tab, then click on ‘Manage this account’ next to your SIP ID. On the next screen, under ‘Call from your own VoIP device’ you will find your ‘SIP ID’, ‘SIP Password’ and ‘Server’ that you’ll need to configure Asterisk, so write them down.

To buy a real phone number located in a country of your choice, first click on the ‘Incoming Numbers’ tab, then under ‘Get more Incoming Numbers’ select the country where you want your new phone number to be located, then click on ‘Continue’; you will see a list with the towns or states of the selected country, and you will have to choose in which town or state you want your number to be located; click on ‘Select’ or ‘View Locations’, then click on ‘Purchase’ or on ‘Select’ then ‘Purchase’.

Please note that for some countries, like Germany, to be able to buy a local number, you have to be a resident of that country. When selecting a number located in a town of such a country, you will have to send the copy of a bill or of an ID card showing that you are a resident of the country.

After you have bought a local phone number, click on the ‘Incoming Numbers’ tab, then under ‘Your Incoming Numbers’, click on the ‘Manage Number’ link next to the local number. Then, under ‘Forward incoming calls’, click on ‘Forward calls to a SIP URI (advanced)’ and in the text box displayed below enter:

sip:8611@123.123.123.123:5827

where 8611 is the name of the extension configured in Asterisk, where you want all the incoming calls to be forwarded by Localphone, 123.123.123.123 is the public IP address of your server, and 5827 is the custom Asterisk port that you have set up earlier. Then click on ‘Update’. With these settings in place, all the calls to your newly acquired local phone number will be forwarded by Localphone to your Asterisk server, to extension 8611. You can then configure Asterisk in such a way that all calls received by extension 8611 will be routed to other specific extension, where a person can pick up the call with a browser phone or a hardphone.

If you acquire more than one real phone number from Localphone, you can configure the other numbers in a similar way. You can forward the calls from all the real phone numbers to the same extension, 8611, or you can forward the calls from each number to a different extension. So, you forward the calls from the first phone number to 8611, the calls from the second phone number to 8612, the calls from the third phone number to 8613, etc.

Please note that Localphone charges only for outbound calls and not for inbound calls. This means that you will pay a price per minute of phone conversation only for the phone calls that you make. The price per minute varies depending on the location of the receiver, as shown here.

Please also note that the phone numbers acquired from Localphone are not suitable for calls to emergency services, so, you won’t be able to call emergency services from a Localphone number.

25.8.1. Number of concurrent inbound/outbound calls when using Localphone

By default, a Localphone account has one SIP ID and allows:

– 2 concurrent (simultaneous) outbound or inbound calls. Additional SIP channels can be requested from their support team, so that more concurrent outbout and inbound calls can be made.

If you request and obtain several SIP IDs and you want to use them to make calls, you will need to buy real phone numbers and attach them as ‘Caller IDs’ to the SIP IDs, otherwise the receivers will see your calls as coming from the SIP IDs (7 digit numbers) instead of real phone numbers. These 7 digit numbers won’t look professional and the receivers won’t be able to call you back on those numbers.

25.9. Configure Asterisk to connect to a Telnyx account

Edit the /etc/asterisk/pjsip.conf file:

nano /etc/asterisk/pjsip.conf

Add the following lines at the bottom of the file, below the [transport-wss] section added earlier:

; Telnyx

[telnyx-reg]
  type=registration
  transport=transport-udp
  outbound_auth=telnyx-auth
  server_uri=sip:sip.telnyx.com:5060
  client_uri=sip:telnyxasterisk@sip.telnyx.com:5060
  auth_rejection_permanent=no

[telnyx-auth]
  type=auth
  auth_type=userpass
  username=telnyxasterisk
  password=c2v?5*Su9J!26?JC!9E

[telnyx]
  type=aor
  contact=sip:telnyxasterisk@sip.telnyx.com
  max_contacts=250

[telnyx]
  type=endpoint
  transport=transport-udp
  context=context-in
  disallow=all
  allow=ulaw
  allow=alaw
  direct_media=no
  from_user=13010101010
  from_domain=sip.telnyx.com
  outbound_auth=telnyx-auth
  aors=telnyx

[telnyx-identify]
  type=identify
  endpoint=telnyx
  match=192.76.120.10
  match=64.16.250.10
  match=185.246.41.140
  match=185.246.41.141

Replace telnyxasterisk with the username of the SIP connection that you have set up earlier in your Telnyx account, on the ‘Voice’, ‘SIP Trunking’ page, on the ‘SIP Connections’ tab; replace c2v?5*Su9J!26?JC!9E with the password set up for the telnyxasterisk user, and 13010101010 with the real phone number acquired from Telnyx, with which you associated the SIP connection with the telnyxasterisk user. The list of real phone numbers with their associated SIP connections can be found in the ‘Numbers’, ‘My Numbers’ section.

Please note that you can replace sip.telnyx.com with a Telnyx SIP proxy located closer to the physical location of your server, such as sip.telnyx.eu, if your server is located in Europe. You can find the list of available proxies here.

If you buy multiple real phone numbers from Telnyx, you will have to create a separate SIP connection for each of them, on the ‘Voice’, ‘SIP Trunking’ page, on the ‘SIP Connections’ tab of your Telnyx account, in the same way as you did it for your first phone number. This means that each real phone number will have a separate SIP connection created in Telnyx, with a separate pair of usernames and passwords. After you create each SIP connection, go to the ‘Numbers’, ‘My Numbers’ section of your Telnyx account and assign each SIP connection to a separate phone number from the list. You do this by choosing the desired SIP connection from the ‘Connection or App’ drop-down list, on the phone number’s row. Then, you will have to associate each SIP connection with a separate outbound voice profile. To do this, go to ‘Voice’, ‘Outbound Voice Profiles’, and repeat the following steps for each outbound voice profile: create a new outbound voice profile by clicking ‘Add New Profile’, enter a name in the ‘Name’ field, click the ‘Create’ button, then under ‘Associated Connections and Applications’ click the ‘Add connections/apps to profile’ button, then select the name of the SIP connection by checking its checkbox, then click ‘Add Connections/Apps to profile’, then under ‘Available Regions and Countries’ select all the regions and countries to which you want to be able to make calls, by clicking their name, then click ‘Save’. After you make all these configurations in your Telnyx account you will need to open the /etc/asterisk/pjsip.conf file on your server and add a section similar to the one displayed above for every SIP connection that you created in your Telnyx account. Thus, each Telnyx SIP connection will have a separate section in the /etc/asterisk/pjsip.conf file. Of course, each section will have its own username, password and real phone number associated with it.

Please note that the headers of each configuration block, like [telnyx-reg], [telnyx-auth], etc., have to be different for different sections. To be more clear, if you want to add a new section for user telnyxasterisk2 with password v4r?*5Su5J!26!Jz4Y and phone number 13030303030, the configuration section will look like this:

[telnyx-reg2]
type=registration
transport=transport-udp
outbound_auth=telnyx-auth2
server_uri=sip:sip.telnyx.com:5060
client_uri=sip:telnyxasterisk2@sip.telnyx.com:5060
auth_rejection_permanent=no

[telnyx-auth2]
type=auth
auth_type=userpass
username=telnyxasterisk2
password=v4r?*5Su5J!26!Jz4Y

[telnyx2]
type=aor
contact=sip:telnyxasterisk2@sip.telnyx.com
max_contacts=250

[telnyx2]
type=endpoint
transport=transport-udp
context=context-in
disallow=all
allow=ulaw
allow=alaw
direct_media=no
from_user=13030303030
from_domain=sip.telnyx.com
outbound_auth=telnyx-auth2
aors=telnyx2

[telnyx-identify2]
type=identify
endpoint=telnyx2
match=192.76.120.10
match=64.16.250.10
match=185.246.41.140
match=185.246.41.141

Restart Asterisk:

systemctl restart asterisk

To test if your Asterisk server has successfully registered to Telnyx use the Asterisk CLI (Command Line Interface). First run:

asterisk -rv

The output will look similar to this:

Asterisk 18.0.0, Copyright (C) 1999 - 2018, Digium, Inc. and others.
Created by Mark Spencer <markster@digium.com>
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Connected to Asterisk 18.0.0 currently running on host (pid = 2846)
host*CLI> 

Then run:

pjsip show endpoints

In the list of endpoints you should see a section like this:

 Endpoint:  telnyx                               Not in use    0 of inf
    OutAuth:  telnyx-auth/telnyxasterisk
        Aor:  telnyx                                           250
      Contact:  telnyx/sip:telnyxasterisk@sip.telnyx.eu      b4545ecb7c NonQual         nan
  Transport:  transport-udp             udp      0      0  0.0.0.0:5827
   Identify:  telnyx-identify/telnyx
        Match: 192.76.120.21/32
        Match: 64.16.250.21/32
        Match: 185.246.41.140/32
        Match: 185.246.41.141/32

where telnyxasterisk is the username configured in the [telnyx-auth] block and 5827 is the custom Asterisk port.

Not in use means that your Asterisk server has successfully registered to Telnyx and that currently the telnyx endpoint is not used in phone conversations. If instead of Not in use you had seen Unavailable, it would have meant that the connection hasn’t been established.

25.10. Configure Asterisk to connect to a Localphone account

Edit the /etc/asterisk/pjsip.conf file:

nano /etc/asterisk/pjsip.conf

Add the following lines at the bottom of the file, below the [transport-wss] section added earlier:

; Localphone

[localphone]
type=registration
transport=transport-udp
outbound_auth=localphone
client_uri=sip:7654321@localphone.com:5060
server_uri=sip:localphone.com:5060
auth_rejection_permanent=no
contact_user=7654321

[localphone]
type=auth
auth_type=userpass
username=7654321
password=j5V9tB9Hw

[localphone]
type=aor
max_contacts=500
contact=sip:7654321@localphone.com

[localphone]
type=endpoint
transport=transport-udp
context=context-in
disallow=all
allow=ulaw
allow=alaw
direct_media=no
from_user=7654321
from_domain=localphone.com
outbound_auth=localphone
aors=localphone

[localphone]
type=identify
endpoint=localphone
match=94.75.247.45
match=95.211.119.240

Replace 7654321 with the real SIP ID provided by Localphone, and j5V9tB9Hw with the real password set up in your Localphone account.

As mentioned earlier, you can request and obtain multiple SIP IDs from Localphone, to be able to have more concurrent phone calls. One SIP ID allows two concurrent calls. If you have multiple SIP IDs in your Localphone account and you want to use them, you will have to add a section similar to the one presented above, for each separate SIP ID that you want to use. Of course, in each section, the password in the password parameter has to be the one associated with the respective SIP ID. Please note that the headers of each configuration block, like [localphone], have to be different for different sections. To be more clear, if you want to add a new section for the SIP ID 7567567 and password w4V9tG5HQ, the configuration section will look like this:

[localphone2]
type=auth
auth_type=userpass
username=7567567
password=w4V9tG5HQ

[localphone2]
type=aor
max_contacts=250
contact=sip:7567567@localphone.com

[localphone2]
type=endpoint
transport=transport-udp
context=context-in
disallow=all
allow=ulaw
allow=alaw
direct_media=no
from_user=7567567
from_domain=localphone.com
outbound_auth=localphone2
aors=localphone2

[localphone2]
type=identify
endpoint=localphone2
match=94.75.247.45
match=95.211.119.240

If you want to add a section for a third SIP ID, the headers will be [localphone3], etc. As mentioned before, if you want to use multiple Localphone SIP IDs to make calls, you will want to buy real phone numbers and assign each phone number to each SIP ID as its Sender ID, otherwise the receivers will see your calls as coming from the SIP ID instead of a real phone number.

If you buy multiple real phone numbers from Localphone, you can assign each phone number as Sender ID to only one SIP ID. All the calls that each phone number receives can be forwarded to a separate Asterisk extension on your server, or you can forward all the calls received by all your phone numbers to one single Asterisk extension. The way you forward the calls received by a phone number bought from Localphone to an Asterisk extension was described earlier, in the ‘Buy a real phone number and configure a localphone.com account’ chapter.

Restart Asterisk:

systemctl restart asterisk

To test if your Asterisk server has successfully registered to Localphone use the Asterisk CLI (Command Line Interface). First run:

asterisk -rv

The output will look similar to this:

Asterisk 18.0.0, Copyright (C) 1999 - 2018, Digium, Inc. and others.
Created by Mark Spencer <markster@digium.com>
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Connected to Asterisk 18.0.0 currently running on host (pid = 2846)
host*CLI> 

Then run:

pjsip show endpoints

In the list of endpoints you should see a section like this:

 Endpoint:  localphone                           Not in use    0 of inf
    OutAuth:  localphone/7654321
        Aor:  localphone                                       250
      Contact:  localphone/sip:7654321@localphone.com      c53eb464e2 NonQual         nan
  Transport:  transport-udp             udp      0      0  0.0.0.0:5827
   Identify:  localphone/localphone
        Match: 94.75.247.45/32
        Match: 95.211.119.240/32

where 7654321 is the username configured in the [localphone] auth block, as well as your Localphone SIP ID, and 5827 is the custom Asterisk port.

Not in use means that your Asterisk server has successfully registered to Localphone and that currently the localphone endpoint is not used in phone conversations. If instead of Not in use you had seen Unavailable, it would have meant that the connection hasn’t been established.

25.11. Create the DTLS certificates that will be used by Asterisk endpoints

For Asterisk to accept the DTLS certificate and private key used by endpoints, you will have to create them manually by using a script designed to generate such certificates and keys. Navigate to the directory where you extracted the Asterisk archive, and then to contrib/scripts, like this:

cd /usr/src/asterisk-18.0.0/contrib/scripts

Copy the script to /etc/asterisk/keys:

cp ast_tls_cert /etc/asterisk/keys

Navigate to /etc/asterisk/keys:

cd /etc/asterisk/keys

You have to modify the default valability of the certificates that will be generated, so open the script:

nano ast_tls_cert

Search for the following lines:

openssl req -new -config ${CACFG} -x509 -days 365 -key ${CAKEY} -out ${CACERT} > /dev/null

openssl x509 -req -days 365 -in ${base}.csr -CA ${CACERT} -CAkey ${CAKEY} -set_serial 01 -out ${base}.crt > /dev/null

and replace 365 with 73000 so that you won’t have to worry to renew the SSL certificate after one year.

Then run the script like this:

./ast_tls_cert -C 123.123.132.123 -O "Company Name" -d /etc/asterisk/keys

Replace 123.123.132.123 with the public IP of your server. You can leave “Company name” as it is. Enter a passphrase for the /etc/asterisk/keys/ca.key file when prompted, then enter it again three more times, when required. This will generate the necessary certificate and key and place them in /etc/asterisk/keys.

Set the correct ownership for the /etc/asterisk/keys directory and its content and change permissions for ast_tls_cert:

chown -R asterisk:asterisk /etc/asterisk/keys
chmod 700 /etc/asterisk/keys/ast_tls_cert

25.12. Testing Asterisk

Before designing and implementing a dial plan adapted to your specific situation, it’s recommended to test making and receiving calls to/from a real phone number, as well as to/from another extension configured in Asterisk. Please note that after you configure Asterisk as shown in this chapter, to be able to test making and receiving calls to/from real phone numbers and between two extensions, you will need to install either Nextcloud together with the ‘SIP Trip Phone’ application, or Roundpin, as described in the chapters dedicated to installing Nextcloud or Roundpin.

(If, for whatever reason, instead of using Telnyx or Localphone as a SIP provider, you want to use Twilio or Flowroute or Vonage, this page explains how to connect your Asterisk server to Twilio/Flowroute/Vonage.)

First edit the /etc/asterisk/pjsip.conf file:

nano /etc/asterisk/pjsip.conf

Add the following sections at the bottom of the file, below the section(s) for Telnyx and/or Localphone:

[601]
type=aor
max_contacts=250

[auth601]
type=auth
auth_type=userpass
username=601
password=Y24bE9vtt4wL2szK9q

[601]
type=endpoint
context=context-out
message_context=textmessages
aors=601
auth=auth601
transport=transport-wss
webrtc=yes
disallow=all
allow=ulaw
allow=alaw
allow=vp8
allow=h264
max_audio_streams=10000000
max_video_streams=10000000
dtls_cert_file=/etc/asterisk/keys/asterisk.pem
dtls_private_key=/etc/asterisk/keys/asterisk.key

[601]
type=identify
endpoint=601
match=123.123.123.123



[602]
type=aor
max_contacts=250

[auth602]
type=auth
auth_type=userpass
username=602
password=9V4bR9vtt42szK5J

[602]
type=endpoint
context=context-out
message_context=textmessages
aors=602
auth=auth602
transport=transport-wss
webrtc=yes
disallow=all
allow=ulaw
allow=alaw
allow=vp8
allow=h264
max_audio_streams=10000000
max_video_streams=10000000
dtls_cert_file=/etc/asterisk/keys/asterisk.pem
dtls_private_key=/etc/asterisk/keys/asterisk.key

[602]
type=identify
endpoint=602
match=123.123.123.123


[publish-extension-state]
type=outbound-publish
outbound_auth=auth601,auth602
server_uri=sip:123.123.123.123
from_uri=sip:123.123.123.123
to_uri=sip:123.123.123.123
event=presence
multi_user=yes
@body=application/pidf+xml

Replace 123.123.123.123 with the public IP address of your server, and Y24bE9vtt4wL2szK9q and 9V4bR9vtt42szK5J with your own passwords.

The [publish-extension-state] block is needed by Asterisk to publish extension state information, so that applications like Roundpin can display real-time extension states like: Ringing, On the phone, On hold, Unavailable, etc.

Next make a copy of the /etc/asterisk/ari.conf file:

cp /etc/asterisk/ari.conf /etc/asterisk/ari.conf_orig

Open the /etc/asterisk/ari.conf file:

nano /etc/asterisk/ari.conf

Edit it as follows:

[general]
enabled = yes       ; When set to no, ARI support is disabled.

pretty = yes

allowed_origins = 0.0.0.0:8088,0.0.0.0:8089


;channelvars = var1,var2,var3

[601]
type=user
read_only=no
password=Y24bE9vtt4wL2szK9q

[602]
type=user
read_only=no
password=9V4bR9vtt42szK5J

Next, make a copy of the original /etc/asterisk/extensions.conf file:

cp /etc/asterisk/extensions.conf /etc/asterisk/extensions.conf_orig

Open the /etc/asterisk/extensions.conf file for editing:

nano /etc/asterisk/extensions.conf

Add the following lines at the bottom of this file:

[context-out]

autohints = yes

; Dial external numbers with Telnyx
exten => _9.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)
exten => _9.,2,Answer()
exten => _9.,3,Hangup()

; Dial external numbers with Localphone
exten => _8.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _8.,2,Answer()
exten => _8.,3,Hangup()


; Dial extension 601
exten => 601,1,Dial(PJSIP/601,60)
exten => 601,2,Answer()
exten => 601,3,Hangup()

; Dial extension 602
exten => 602,1,Dial(PJSIP/602,60)
exten => 602,2,Answer()
exten => 602,3,Hangup()


[context-in]

autohints = yes

exten => 12020202020,1,Goto(context-out,601,1)
exten => 8561,1,Goto(context-out,601,1)


[textmessages]

autohints = yes

exten => 601,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 602,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

Replace 12020202020 with your real phone number acquired from Telnyx (if you use Telnyx). Please note that the phone number must start with the country calling code. In this example it’s the US country calling code, 1. In the Acquire a real phone number from Telnyx and configure a telnyx.com account chapter we explained how to buy a real phone number from Telnyx and how to configure a telnyx.com account to be able to make and receive phone calls using that phone number.

Replace 8561 with the extension to which you forwarded the calls received by your real phone number acquired from Localphone (if you use Localphone). The Acquire a real phone number from Localphone and configure a localphone.com account chapter explained how to forward calls to the 8561 extension.

The autohints = yes directive enables the automatic creation of extension state hints, which are used to send extension states (Ringing, On the phone, On hold, Unavailable, etc.) to applications like Roundpin.

Restart Asterisk:

systemctl restart asterisk

Now you should be able to make and receive phone calls using your phone number acquired from Telnyx/Localphone. You should be able also to make phone calls between extension 601 and 602. To make phone calls to/from a real phone number you can use your mobile/landline phone and ‘SIP Trip Phone’ or ‘Roundpin’ (after you install them as explained in the chapters dedicated to their installation). To make calls between the two extensions configured in Asterisk, 601 and 602, you can use either ‘SIP Trip Phone’ or ‘Roundpin’.

After you verify that everything works as exptected, you can design and implement a complete dial plan adapted to your business/use case, by following the steps described in the ‘Design and implement a dial plan’ chapter from below.

25.13. Design and implement a dial plan

We’ll describe the most frequent 4 dial plan classes, applicable to a small company. Let’s say the company has 6 phones (in this case 6 browser phones, but any of them, or all of them can be replaced with hardphones if desired; for hardphones, some settings must be changed in the /etc/asterisk/pjsip.conf file, as we’ll explain below). The 6 phones belong to the following departments: Sales, Billing, Technical Support, Operator/Secretary, CEO, CTO. The 4 most frequent scenarios for handling incoming calls to these 6 phones are the following:

1. All incoming calls are directed by Asterisk to an IVR (Interactive Voice Response) or auto-attendant, which will offer an audio presentation of all the possible options. When the caller presses a key, the call will be directed to the requested extension. If that extension is already in use the caller is put on hold. If the extension is disconnected (the browser phone is closed), the caller will be directed to the voicemail. The sales, billing and technical support departments and the operator can be reached directly by pressing a key, as instructed by the IVR. Any caller who wants to speak with the CEO or CTO has to speak first with the operator, who will transfer their call to the CEO or CTO.

2. All incoming calls are directed to one extension, that of a human operator/secretary/office assistant who will pick up and then transfer the call to the extension that the caller needs. If the operator’s extension is in use, the caller is put on hold. If it’s disconnected, the caller is sent to the voicemail. If the extension where the call is transferred is in use or disconnected, the caller is put on hold or sent to the voicemail, respectively.

3. Each incoming call is directed to all the extensions of the company so that all the phones ring simultaneously and once someone picks up a phone, all the other connections will be dropped. If all the extensions are in use, the caller will be put on hold, in a queue. If all the extensions are disconnected, the caller will be sent to the voicemail.

4. The company has one phone number for regular phone calls and all phone calls to this number are directed towards an IVR and treated as in the first scenario. The company also has a secondary phone number for the CEO, and all incoming calls to this number are routed directly to the CEO’s extension. If the CEO’s extension is already in use, the caller will be put on hold, if the phone is disconnected (the browser phone is closed) the caller will be sent to the voicemail.

The dial plans for all the other situations in which a small company might be, can be deduced from the dial plans for the 4 scenarios described above.

There will be 7 extensions:

1. IVR: extension 8611.

2. Sales Department: extension 601.

3. Billing Department: extension 602.

4. Technical Support Department: extension 603.

5. Operator: extension 604.

6. CEO: extension 631.

7. CTO: extension 632.

You can change these extension numbers to something else if you want to.

The number of an extension, 603 for example, can be a mixture of numbers and letters or only letters. For usability and simplicity reasons, it’s recommended to set up extensions made up of numbers only. In the /etc/asterisk/pjsip.conf file, the number of the extension has to appear in the header of the aor and endpoint blocks, as well as in the username from the auth block, as we will show below.

When you choose the number of an extension, it’s recommended to choose a number of three digits, with the first digit greater than or equal to 6, to avoid overlapping between extension numbers and IVR menu numbers. In general an IVR menu will offer keys from 0 to 4 or 5 as options to the caller, so, once the caller presses an IVR option key, Asterisk knows immediately that the caller entered an IVR option and didn’t dial an extension, because no extension begins with digits smaller than 6. In case of overlap, after the caller presses a key, Asterisk will wait to see if the caller will press other keys, so as to decide if it was a regular extension that was dialed or just an IVR option.

Open the /etc/asterisk/pjsip.conf file:

nano /etc/asterisk/pjsip.conf

At the bottom of this file enter the following settings which will remain the same for all the 4 scenarios described above:

; Sales

[601]
type=aor
max_contacts=250

[auth601]
type=auth
auth_type=userpass
username=601
password=Y24bE9vtt4wL2szK9q

[601]
type=endpoint
context=context-out
message_context=textmessages
aors=601
auth=auth601
transport=transport-wss
webrtc=yes
disallow=all
allow=ulaw
allow=alaw
allow=vp8
allow=h264
max_audio_streams=10000000
max_video_streams=10000000
dtls_cert_file=/etc/asterisk/keys/asterisk.pem
dtls_private_key=/etc/asterisk/keys/asterisk.key

[601]
type=identify
endpoint=601
match=123.123.123.123


; Billing

[602]
type=aor
max_contacts=250

[auth602]
type=auth
auth_type=userpass
username=602
password=9V4bR9vtt42szK5J

[602]
type=endpoint
context=context-out
message_context=textmessages
aors=602
auth=auth602
transport=transport-wss
webrtc=yes
disallow=all
allow=ulaw
allow=alaw
allow=vp8
allow=h264
max_audio_streams=10000000
max_video_streams=10000000
dtls_cert_file=/etc/asterisk/keys/asterisk.pem
dtls_private_key=/etc/asterisk/keys/asterisk.key

[602]
type=identify
endpoint=602
match=123.123.123.123


; Technical support

[603]
type=aor
max_contacts=250

[auth603]
type=auth
auth_type=userpass
username=603
password=r74bQ9vtS4wL2sz9V

[603]
type=endpoint
context=context-out
message_context=textmessages
aors=603
auth=auth603
transport=transport-wss
webrtc=yes
disallow=all
allow=ulaw
allow=alaw
allow=vp8
allow=h264
max_audio_streams=10000000
max_video_streams=10000000
dtls_cert_file=/etc/asterisk/keys/asterisk.pem
dtls_private_key=/etc/asterisk/keys/asterisk.key

[603]
type=identify
endpoint=603
match=123.123.123.123



; Operator

[604]
type=aor
max_contacts=250

[auth604]
type=auth
auth_type=userpass
username=604
password=2t4GE9vttwL2szLcD

[604]
type=endpoint
context=context-out
message_context=textmessages
aors=604
auth=auth604
transport=transport-wss
webrtc=yes
disallow=all
allow=ulaw
allow=alaw
allow=vp8
allow=h264
max_audio_streams=10000000
max_video_streams=10000000
dtls_cert_file=/etc/asterisk/keys/asterisk.pem
dtls_private_key=/etc/asterisk/keys/asterisk.key

[604]
type=identify
endpoint=604
match=123.123.123.123


; CEO

[631]
type=aor
max_contacts=250

[auth631]
type=auth
auth_type=userpass
username=631
password=Wz4E9vt54wL2sKBK

[631]
type=endpoint
context=context-out
message_context=textmessages
aors=631
auth=auth631
transport=transport-wss
webrtc=yes
disallow=all
allow=ulaw
allow=alaw
allow=vp8
allow=h264
max_audio_streams=10000000
max_video_streams=10000000
dtls_cert_file=/etc/asterisk/keys/asterisk.pem
dtls_private_key=/etc/asterisk/keys/asterisk.key

[631]
type=identify
endpoint=631
match=123.123.123.123

; CTO

[632]
type=aor
max_contacts=250

[auth632]
type=auth
auth_type=userpass
username=632
password=6B4bE9vt4wL9szK4A

[632]
type=endpoint
context=context-out
message_context=textmessages
aors=632
auth=auth632
transport=transport-wss
webrtc=yes
disallow=all
allow=ulaw
allow=alaw
allow=vp8
allow=h264
max_audio_streams=10000000
max_video_streams=10000000
dtls_cert_file=/etc/asterisk/keys/asterisk.pem
dtls_private_key=/etc/asterisk/keys/asterisk.key

[632]
type=identify
endpoint=632
match=123.123.123.123


[publish-extension-state]
type=outbound-publish
outbound_auth=auth601,auth602,auth603,auth604,auth631,auth632
server_uri=sip:123.123.123.123
from_uri=sip:123.123.123.123
to_uri=sip:123.123.123.123
event=presence
multi_user=yes
@body=application/pidf+xml

Replace 123.123.123.123 with the public IP address of your server. Also replace the passwords with your own passwords, which should be strong and different from one extension to the other. You can also change the number of each extension.

Next, make a copy of the /etc/asterisk/ari.conf file:

cp /etc/asterisk/ari.conf /etc/asterisk/ari.conf_orig

Open the /etc/asterisk/ari.conf file:

nano /etc/asterisk/ari.conf

Edit it as follows:

[general]
enabled = yes       ; When set to no, ARI support is disabled.

pretty = yes

allowed_origins = 0.0.0.0:8088,0.0.0.0:8089


[601]
type=user
read_only = no
password=5g7vt25ht4qpD6szjc

[602]
type=user
read_only = no
password=7vt25htv8qpY6szj2s

[603]
type=user
read_only = no
password=b5vt2ht4qkD6szjz8o

[604]
type=user
read_only = no
password=8vt25ht4qpD6szjlp2

[631]
type=user
read_only = no
password=gtvt25ht4qpD6szjk9q

[632]
type=user
read_only = no
password=j2vt25ht8qpD6szne6

Replace the extension names and passwords with your real extension names and passwords. The settings from above will remain the same for all the 4 scenarios.

25.13.1. Custom audio messages

Creating a professional phone system using Asterisk implies creating custom audio messages. You will need custom audio messages for the following 3 purposes:

  • IVR prompts
  • on hold messages (mixed with music)
  • voicemail greetings (unavailable or busy messages and a general voicemail box greeting)

Before making all the necessary configurations for the 4 scenarios mentioned above, you should make sure you have all the IVR prompts, on hold messages and voicemail greetings recorded and ready to use. To create professional audio messages, you should first write the messages down and then choose one of the following three methods:

  • you record yourself reading the prompts and messages with a sound recorder like Audacity (www.audacityteam.org) in the wav format. You can also use Audacity to cut and edit the files, if needed.
  • you ask one of your collaborators/friends/employees to record the prompts and messages for you.
  • you ask a voice actor to record the prompts and messages for you in exchange for a fee. You can use the services of sites like www.snaprecordings.com or you can find much cheaper voice over services on www.fiverr.com.

If the recording is a unique wav file with all the prompts and messages, you have to cut it according to its sections into multiple files and then upload those files to your server where you’ll convert them to 8000 Hz wav files with the sox tool, as we’ll explain below. If the sound files are mp3 files, you should also use the sox tool to convert them to 8000 Hz wav files.

If you need gratis, royalty free on hold music, you have two main options: you waste many hours of your time searching for such music on the Internet and finding dozens of so called ‘free music tracks’ only to realize afterwards that you’ll have to pay to be able to use them commercially, or you use the Bach’s Goldberg Variations played by Kimiko Ishizaka (the ‘Open Goldberg Variations’ project) and licenced under the Creative Commons Zero license (CC0 1.0) which means that they are released into the public domain and you are free to use them for any purpose, including commercially. You can download any track you like from here.

You may also find royalty free music on https://musopen.org but some pieces listed there as part of the public domain may still have copyright restrictions that the site is not aware of.

25.13.1.1. Examples of professional custom messages for an Asterisk based phone system

Below you can find examples of professional IVR prompts, voicemail and on hold messages, suitable for the first of the four scenarios mentioned above. You can adapt these messages to suit your own situation.

25.13.1.1.1. IVR prompts

Hello, thank you for calling Global Weasels LLC.

For sales press 1.

For billing press 2.

For technical support press 3.

To speak with the operator press 4.

To leave us a message press 5.

25.13.1.1.2. On hold messages
25.13.1.1.2.1. General on hold message

[music]

Hello, thank you for calling Global Weasels LLC. Our phone lines are currently busy. We can get to your call in just a moment, if you don’t mind holding.

[music]

Thank you for holding, someone will be available shortly to assist you.

[music]

We apologize for the long wait. If you’d prefer to leave a voicemail, press 5 to leave your name, phone number and inquiry. We will call you back as soon as we can. If you want to speak with the operator press 4. Otherwise, feel free to continue to hold.

[music]

[repeat the last paragraph]

[music]

[repeat the last paragraph]

[music]

We apologize for the long wait. Unfortunately no one in this department has been available to take your call. If you prefer to leave a voicemail, press 5 to leave your name, phone number and inquiry and we will call you back as soon as possible. If you want to speak with the operator press 4. Otherwise, please call back later. Thank you for your understanding.

[wait 7 seconds]

[hang up]

25.13.1.1.2.2. On hold message for CEO

[music]

Hello, this is Jim Jimsky, CEO at Global Weasels LLC. I can’t answer the phone right now, but I’ll get to your call in just a moment, if you don’t mind holding.

[music]

I apologize for the long wait. If you’d prefer to leave a voicemail, press 7 to leave your name, phone number and request and I will call you back as soon as I can. If you want to speak with the operator press 4. Otherwise, feel free to continue to hold.

[music]

[repeat the last paragraph]

[music]

[repeat the last paragraph]

[music]

I apologize for the long wait. Unfortunately I can’t take your call right now. If you prefer to leave a voicemail, press 5 to leave your name, phone number and inquiry and I will call you back as soon as possible. If you want to speak with the operator press 4. Otherwise, please call back later. Thank you for your understanding.

[wait 7 seconds]

[hang up]

25.13.1.1.2.3. On hold message for CTO

[music]

Hello, this is Ben Binsky, CTO at Global Weasels LLC. I can’t answer the phone right now, but I’ll get to your call in just a moment, if you don’t mind holding.

[music]

I apologize for the long wait. If you’d prefer to leave a voicemail, press 8 to leave your name, phone number and request and I will call you back as soon as I can. If you want to speak with the operator press 4. Otherwise, feel free to continue to hold.

[music]

[repeat the last paragraph]

[music]

[repeat the last paragraph]

[music]

I apologize for the long wait. Unfortunately I can’t take your call right now. If you prefer to leave a voicemail, press 5 to leave your name, phone number and inquiry and I will call you back as soon as possible. If you want to speak with the operator press 4. Otherwise, please call back later. Thank you for your understanding.

[wait 7 seconds]

[hang up]

25.13.1.1.3. Voicemail messages
25.13.1.1.3.1. Unavailable messages for company departments

Hello, you’ve reached the Sales Department at Global Weasels LLC. / Hello, you’ve reached the Billing Department at Global Weasels LLC. / Hello, you’ve reached the Technical Support Department at Global Weasels LLC. / Hello, you’ve reached the operator at Global Weasels LLC.

At the moment no one is available to take your call, but if you leave your name, phone number and a brief message after the tone, we will return your call as soon as possible. Thank you!

25.13.1.1.3.2. Unavailable message for CEO

Hello, this is Jim Jimsky, CEO at Global Weasels LLC. I can’t answer the phone right now, but if you leave me a message with your name, phone number and your request, I will return your call as soon as I can. Thank you!

25.13.1.1.3.3. Unavailable message for CTO

Hello, this is Ben Binsky, CTO at Global Weasels LLC. I can’t take your call at the moment, but if you leave me a message with your name, phone number and your request, I will return your call as soon as possible. Thank you!

25.13.1.1.3.4. General voicemail box message

Please leave your message, name, phone number or email address after the tone and we will contact you as soon as possible. When done, hang up or press the pound key. Thank you!

25.13.2. Configure voicemail

The configurations in this chapter will remain the same for all the 4 scenarios mentioned above. Make a copy of the original /etc/asterisk/voicemail.conf file:

cp /etc/asterisk/voicemail.conf /etc/asterisk/voicemail.conf_orig

Open the file for editing:

nano /etc/asterisk/voicemail.conf

Change the maximum number of messages per folder. In the [general] section, search for:

; Maximum number of messages per folder.  If not specified, a default value
; (100) is used.  Maximum value for this option is 9999.  If set to 0, a
; mailbox will be greetings-only.

Below the paragraph from above enter:

maxmsg=1000

Edit the maximum length in seconds that a voicemail message is allowed to have. In the [general] section, below ; Maximum length of a voicemail message in seconds enter:

maxsecs=3600

Also, at the bottom of the file enter the following lines:

[voicemail-context]

601 => 4542,Frank Fransky,sales@example.com,,attach=yes
602 => 2432,George Gorsky,billing@example.com,,attach=yes
603 => 1542,Matt Mathewson,tech-support@example.com,,attach=yes
604 => 2426,Conrad Consky,operator@example.com,,attach=yes
631 => 6232,Tom Tomsky,ceo@example.com,,attach=yes
632 => 7492,Verner Vernsky,cto@example.com,,attach=yes
650 => 8271,General Voicemail Box,general-voicemail@example.com,,attach=yes

Change the extension numbers if you want to, replace the passwords that appear after the ‘=>’ sign, which can be numbers only, so that the users can enter them easily using a phone’s keypad, replace the names and the email addresses where the voicemail messages will be sent as attachments. Of course, if you haven’t created the email addresses for each department already, you will have to create them using Postfix Admin.

Restart Asterisk to apply the changes:

systemctl restart asterisk

25.13.2.1. Give user asterisk permission to send emails

To allow Asterisk to send the voicemail messages as email attachments to the addresses you specified in the /etc/asterisk/voicemail.conf file, you will have to give user asterisk the right to send emails using the Sendmail application that comes with Postfix. Open the /etc/postfix/main.cf file:

nano /etc/postfix/main.cf

Make sure that the authorized_submit_users line looks like this:

authorized_submit_users = !sshusername, !ftpusername, vmail, root, www-data, asterisk

Replace sshusername with the username of your SSH user and ftpusername with the username of your FTP user. They won’t be allowed to send emails because they don’t need to.

Restart Postfix:

systemctl restart postfix

25.13.2.2. Delete old voicemail messages

It should be noted that voicemail can be configured in such a way that all voicemail messages are removed from their voicemail box right after they are submitted as email attachments to the proper email addresses. This can be done by setting the delete parameter to yes for a specific extension in the /etc/asterisk/voicemail.conf file, like this:

601 => 4542,Frank Fransky,sales@example.com,,attach=yes|delete=yes

This has the advantage that it saves storage space and you don’t have to worry about deleting old voicemail messages, but it has the disadvantage that you won’t be able to listen to your voicemail messages from your phone. When you’ll access your voicemail box from your phone, you will always find it empty.

To be able to listen to voicemail messages from your phone (and also receive them as email attachments) you have to configure voicemail as we showed in the ‘Configure voicemail’ chapter, where we didn’t use the delete parameter. However, in this situation you’ll have to use a script to periodically delete voicemail messages older than a specified number of days. In this way, your voicemail boxes will never become full. If a voicemail box is full, Asterisk will tell any caller who wants to leave a message that the respective box is full and the message can’t be saved.

To periodically delete old voicemail messages, first copy the messages-expire.pl script that comes with Asterisk, from the directory where the original Asterisk downloaded archive has been uncompressed, to the /srv/scripts directory:

cp /usr/src/asterisk-18.0.0/contrib/scripts/messages-expire.pl /srv/scripts

Then change permissions for this script:

chmod 700 /srv/scripts/messages-expire.pl

Open the script for editing:

nano /srv/scripts/messages-expire.pl

Make the following three parameters look like this:

$dir = "/var/spool/asterisk/voicemail";
$context = "voicemail-context";
$age = 90;

Also, search for this line:

    if (-f $dir."/".$mailbox."/".$folder."/msg0000.txt") { next; }

Right below it add the following three lines, so that the script won’t rename the unavailable messages files:

    if (-f $dir."/".$mailbox."/en/unavail.wav") { next; }
    if (-f $dir."/".$mailbox."/en/unavail.gsm") { next; }

Then set up a cronjob to delete all the Asterisk voicemail messages older than 90 days:

crontab -e

Enter the following lines at the end of the file:

# Delete Asterisk voicemail messages older than 90 days every Monday at 2:12 AM
12 2 * * 1 perl /srv/scripts/messages-expire.pl > /dev/null 2>&1

25.13.3. Install the sox package to convert sound files

apt-get install sox libsox-fmt-mp3

If you want to convert an mp3 file to a 8000 Hz wav file using sox run:

sox input.mp3 -r 8000 -c1 output.wav

25.13.4. Location of custom sound files

Once you have written the custom messages, recorded them, edited them if necessary (using Audacity for example; in Debian you can install Audacity by running apt-get install audacity), you will want to copy the finished sound files to the proper location, so that Asterisk can find and use them.

The custom voicemail greeting message (unavailable message) for each extension should be placed in the /var/spool/asterisk/voicemail/voicemail-context/601/en directory, where 601 is the number of the extension. Asterisk will not create the 601 directory and its parent directory until someone leaves a message for extension 601. Therefore, in order to add custom unavailable messages in the directories corresponding to all the extensions, you will need to create them manually like this:

mkdir -p /var/spool/asterisk/voicemail/voicemail-context/601/en
mkdir -p /var/spool/asterisk/voicemail/voicemail-context/602/en
mkdir -p /var/spool/asterisk/voicemail/voicemail-context/603/en
mkdir -p /var/spool/asterisk/voicemail/voicemail-context/604/en
mkdir -p /var/spool/asterisk/voicemail/voicemail-context/631/en
mkdir -p /var/spool/asterisk/voicemail/voicemail-context/632/en
mkdir -p /var/spool/asterisk/voicemail/voicemail-context/650/en

Of course, if instead of English, your phone system uses French, German, etc., /var/spool/asterisk/voicemail/voicemail-context/601/en will become /var/spool/asterisk/voicemail/voicemail-context/601/fr, /var/spool/asterisk/voicemail/voicemail-context/601/de, etc. This also implies that when installing Asterisk you have chosen to install the sound files for French, German, etc. instead of English.

Then set the proper ownership for the /var/spool/asterisk/voicemail/voicemail-context directory and all its content:

chown -R asterisk:asterisk /var/spool/asterisk/voicemail/voicemail-context

It’s recommended to create custom unavailable messages in the wav format (mono, not stereo). If your custom unavailable messages are in the wav format but they are not 8000 Hz, you should convert them to 8000 Hz, because Asterisk won’t read wav files with other frequencies. To convert a wav file to 8000 Hz, run:

sox original.wav -r 8000 -c1 unavail.wav

If you have custom unavailable messages in the gsm format, don’t convert them to wav files to avoid loosing sound quality. Leave the files in their original gsm format, because Asterisk can read gsm files.

If the original custom unavailable messages are in the mp3 format, convert them to 8000 Hz wav files by running commands like this:

sox original.mp3 -r 8000 -c1 unavail.wav

Copy all the custom unavailable messages to the directories mentioned above. Thus, for extension 631, the unavailable message file should have the following path:

/var/spool/asterisk/voicemail/voicemail-context/631/en/unavail.wav

Set the right ownership for the unavailable message file:

chown asterisk:asterisk /var/spool/asterisk/voicemail/voicemail-context/631/en/unavail.wav

All the unavailable message files should be called unavail.wav or unavail.gsm, therefore, don’t change their name to something else.

In the four scenarios, you’ll also need 3 types of on hold messages: one general on hold message for the four departments of the company, one special on hold message for the CEO and one special on hold message for the CTO. The verbal on hold messages are typically mixed with relaxing music, to make waiting more comfortable. First create three separate directories: onhold-general, onhold-ceo, onhold-cto inside the /var/lib/asterisk/sounds/en directory:

cd /var/lib/asterisk/sounds/en/
mkdir onhold-general onhold-ceo onhold-cto

Then copy the on hold messages files to the proper directories like this:

cp /path/to/onhold-general.wav /var/lib/asterisk/sounds/en/onhold-general
cp /path/to/onhold-ceo.wav /var/lib/asterisk/sounds/en/onhold-ceo
cp /path/to/onhold-cto.wav /var/lib/asterisk/sounds/en/onhold-cto

Keep the names of the files as they are (onhold-general.wav, onhold-ceo.wav, onhold-cto.wav), because you will use them later in the /etc/asterisk/musiconhold.conf and /etc/asterisk/queues.conf files. Set the right ownership and permissions for the three newly created directories and their content:

chown -R asterisk:asterisk onhold-general onhold-ceo onhold-cto
chmod 644 onhold-general/* onhold-ceo/* onhold-cto/*

The third category of custom sound files is the file containing the IVR prompts. This file should be copied to the /var/lib/asterisk/sounds/en directory like this:

cp /path/to/ivr-prompts.wav /var/lib/asterisk/sounds/en

Set the right ownership and permissions for this file:

chown asterisk:asterisk ivr-prompts.wav
chmod 644 ivr-prompts.wav

Keep the name of the IVR prompts file as it is (ivr-prompts.wav) because you will use it later.

It goes without saying that the /var/lib/asterisk/sounds/en directory should become /var/lib/asterisk/sounds/fr if you use French instead of English and in the beginning, when you configured Asterisk installation, you selected to install the CORE-SOUNDS-FR-WAV and EXTRA-SOUNDS-FR-WAV sounds for the French language. It should become /var/lib/asterisk/sounds/de for German, /var/lib/asterisk/sounds/it for Italian, etc.

25.13.5. Configure on hold music

First make a copy of the original /etc/asterisk/musiconhold.conf file:

cp /etc/asterisk/musiconhold.conf /etc/asterisk/musiconhold.conf_orig

Open the /etc/asterisk/musiconhold.conf file:

nano /etc/asterisk/musiconhold.conf

Search for the following block:

[default]
mode=files
directory=moh

Right below it place the following blocks:

[onhold-general]
mode=files
directory=/var/lib/asterisk/sounds/en/onhold-general

[onhold-ceo]
mode=files
directory=/var/lib/asterisk/sounds/en/onhold-ceo

[onhold-cto]
mode=files
directory=/var/lib/asterisk/sounds/en/onhold-cto

25.13.6. Configure queues

When multiple callers are manually or automatically routed to an extension that is busy, the appropriate way of dealing with them is to place them in a queue, in the order of their arrival. Then, when the extension becomes available, the first caller in line will be automatically connected to the extension. To implement call queues follow the steps from below.

First make a copy of the original /etc/asterisk/queues.conf file:

cp /etc/asterisk/queues.conf /etc/asterisk/queues.conf_orig

Then open the /etc/asterisk/queues.conf file:

nano /etc/asterisk/queues.conf

Add the following lines at the bottom of the file:

[sales-queue]

context=context-in
musicclass=onhold-general
strategy=linear
retry=4
timeout=1200
announce-holdtime=no
announce-frequency=0
announce-position=no
joinempty=yes
leavewhenempty=no
ringinuse=no
autofill=no
maxlen=0
memberdelay=0
wrapuptime=0
weight=0
member => PJSIP/601

[billing-queue]

context=context-in
musicclass=onhold-general
strategy=linear
retry=4
timeout=1200
announce-holdtime=no
announce-frequency=0
announce-position=no
joinempty=yes
leavewhenempty=no
ringinuse=no
autofill=no
maxlen=0
memberdelay=0
wrapuptime=0
weight=0
member => PJSIP/602

[techsupport-queue]

context=context-in
musicclass=onhold-general
strategy=linear
retry=4
timeout=1200
announce-holdtime=no
announce-frequency=0
announce-position=no
joinempty=yes
leavewhenempty=no
ringinuse=no
autofill=no
maxlen=0
memberdelay=0
wrapuptime=0
weight=0
member => PJSIP/603

[operator-queue]

context=context-in
musicclass=onhold-general
strategy=linear
retry=4
timeout=1200
announce-holdtime=no
announce-frequency=0
announce-position=no
joinempty=yes
leavewhenempty=no
ringinuse=no
autofill=no
maxlen=0
memberdelay=0
wrapuptime=0
weight=0
member => PJSIP/604

[ceo-queue]

context=context-in
musicclass=onhold-ceo
strategy=linear
retry=4
timeout=1200
announce-holdtime=no
announce-frequency=0
announce-position=no
joinempty=yes
leavewhenempty=no
ringinuse=no
autofill=no
maxlen=0
memberdelay=0
wrapuptime=0
weight=0
member => PJSIP/631


[cto-queue]

context=context-in
musicclass=onhold-cto
strategy=linear
retry=4
timeout=1200
announce-holdtime=no
announce-frequency=0
announce-position=no
joinempty=yes
leavewhenempty=no
ringinuse=no
autofill=no
maxlen=0
memberdelay=0
wrapuptime=0
weight=0
member => PJSIP/632


25.13.7. Use the /etc/asterisk/extensions.conf file to implement each of the 4 dial plans

We’ll explain below what settings need to be added to the /etc/asterisk/extensions.conf file for each of the 4 scenarios mentioned above. You should choose and implement the scenario that best fits your use case.

25.13.7.1. The first scenario

The first scenario is the following:

All incoming calls are routed to an IVR, which makes a presentation of all the possible options. When the caller presses a key associated with an extension, the call is directed to the requested extension. If that extension is in use, the caller is put on hold in a queue, if it’s disconnected (the browser phone is closed), the caller is sent to the voicemail. All the 4 departments: Sales, Billing, Technical Support and the operator can be reached by pressing a specific key while listening to the IVR. Any caller who wants to speak with the CEO or CTO has to talk to the operator first, and the operator will transfer their call to the CEO or CTO.

Make a copy of the original /etc/asterisk/extensions.conf file:

cp /etc/asterisk/extensions.conf /etc/asterisk/extensions.conf_orig

Open the file for editing:

nano /etc/asterisk/extensions.conf

Add the following lines at the bottom of this file:

[context-out]

autohints = yes

; Dial external numbers with Telnyx
exten => _9.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)
exten => _9.,2,Answer()
exten => _9.,3,Hangup()

; Dial external numbers with Localphone
exten => _8.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _8.,2,Answer()
exten => _8.,3,Hangup()

; Sales Department
exten => 601,1,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/601)} = UNKNOWN]]?601,2:601,4)
exten => 601,2,VoiceMail(601@voicemail-context,s,u)
exten => 601,3,Hangup()
exten => 601,4,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = INUSE] | [${DEVICE_STATE(PJSIP/601)} = BUSY] | [${DEVICE_STATE(PJSIP/601)} = ONHOLD] | [${DEVICE_STATE(PJSIP/601)} = RINGING]]?601,5:601,8)
exten => 601,5,Answer()
exten => 601,6,Queue(sales-queue,nt,,,1200)
exten => 601,7,Hangup()
exten => 601,8,Dial(PJSIP/601,60)
exten => 601,9,Hangup()

; Billing Department
exten => 602,1,GotoIf($[[${DEVICE_STATE(PJSIP/602)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/602)} = UNKNOWN]]?602,2:602,4)
exten => 602,2,VoiceMail(602@voicemail-context,s,u)
exten => 602,3,Hangup()
exten => 602,4,GotoIf($[[${DEVICE_STATE(PJSIP/602)} = INUSE] | [${DEVICE_STATE(PJSIP/602)} = BUSY] | [${DEVICE_STATE(PJSIP/602)} = ONHOLD] | [${DEVICE_STATE(PJSIP/602)} = RINGING]]?602,5:602,8)
exten => 602,5,Answer()
exten => 602,6,Queue(billing-queue,nt,,,1200)
exten => 602,7,Hangup()
exten => 602,8,Dial(PJSIP/602,60)
exten => 602,9,Hangup()

; Technical Support Department
exten => 603,1,GotoIf($[[${DEVICE_STATE(PJSIP/603)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/603)} = UNKNOWN]]?603,2:603,4)
exten => 603,2,VoiceMail(603@voicemail-context,s,u)
exten => 603,3,Hangup()
exten => 603,4,GotoIf($[[${DEVICE_STATE(PJSIP/603)} = INUSE] | [${DEVICE_STATE(PJSIP/603)} = BUSY] | [${DEVICE_STATE(PJSIP/603)} = ONHOLD] | [${DEVICE_STATE(PJSIP/603)} = RINGING]]?603,5:603,8)
exten => 603,5,Answer()
exten => 603,6,Queue(techsupport-queue,nt,,,1200)
exten => 603,7,Hangup()
exten => 603,8,Dial(PJSIP/603,60)
exten => 603,9,Hangup()

; Operator
exten => 604,1,GotoIf($[[${DEVICE_STATE(PJSIP/604)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/604)} = UNKNOWN]]?604,2:604,4)
exten => 604,2,VoiceMail(604@voicemail-context,s,u)
exten => 604,3,Hangup()
exten => 604,4,GotoIf($[[${DEVICE_STATE(PJSIP/604)} = INUSE] | [${DEVICE_STATE(PJSIP/604)} = BUSY] | [${DEVICE_STATE(PJSIP/604)} = ONHOLD] | [${DEVICE_STATE(PJSIP/604)} = RINGING]]?604,5:604,8)
exten => 604,5,Answer()
exten => 604,6,Queue(operator-queue,nt,,,1200)
exten => 604,7,Hangup()
exten => 604,8,Dial(PJSIP/604,60)
exten => 604,9,Hangup()

; CEO's extension
exten => 631,1,GotoIf($[[${DEVICE_STATE(PJSIP/631)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/631)} = UNKNOWN]]?631,2:631,4)
exten => 631,2,VoiceMail(631@voicemail-context,s,u)
exten => 631,3,Hangup()
exten => 631,4,GotoIf($[[${DEVICE_STATE(PJSIP/631)} = INUSE] | [${DEVICE_STATE(PJSIP/631)} = BUSY] | [${DEVICE_STATE(PJSIP/631)} = ONHOLD] | [${DEVICE_STATE(PJSIP/631)} = RINGING]]?631,5:631,8)
exten => 631,5,Answer()
exten => 631,6,Queue(ceo-queue,nt,,,1200)
exten => 631,7,Hangup()
exten => 631,8,Dial(PJSIP/631,60)
exten => 631,9,Hangup()

; CTO's extension
exten => 632,1,GotoIf($[[${DEVICE_STATE(PJSIP/632)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/632)} = UNKNOWN]]?632,2:632,4)
exten => 632,2,VoiceMail(632@voicemail-context,s,u)
exten => 632,3,Hangup()
exten => 632,4,GotoIf($[[${DEVICE_STATE(PJSIP/632)} = INUSE] | [${DEVICE_STATE(PJSIP/632)} = BUSY] | [${DEVICE_STATE(PJSIP/632)} = ONHOLD] | [${DEVICE_STATE(PJSIP/632)} = RINGING]]?632,5:632,8)
exten => 632,5,Answer()
exten => 632,6,Queue(cto-queue,nt,,,1200)
exten => 632,7,Hangup()
exten => 632,8,Dial(PJSIP/632,60)
exten => 632,9,Hangup()

; Operator
exten => 4,1,Goto(604,1)

; If you dial 5, you can leave a message in the general voicemail box
exten => 5,1,VoiceMail(650@voicemail-context,s,u)
exten => 5,n,Hangup()

; If you dial 7, you can leave a message in the CEO's voicemail box
exten => 7,1,VoiceMail(631@voicemail-context,s,u)
exten => 7,n,Hangup()

; If you dial 8, you can leave a message in the CTO's voicemail box
exten => 8,1,VoiceMail(632@voicemail-context,s,u)
exten => 8,n,Hangup()

; Read voicemail messages
exten => 955,1,Answer(500)
exten => 955,n,VoiceMailMain(@voicemail-context)



[context-in]

autohints = yes

; IVR in case you use Telnyx
exten => 12020202020,1,Ringing()
exten => 12020202020,2,Wait(0.5)
exten => 12020202020,3,Answer()
exten => 12020202020,4,Background(/var/lib/asterisk/sounds/en/ivr-prompts)
exten => 12020202020,5,Wait(2)
exten => 12020202020,6,Goto(12020202020,2)

; IVR in case you use Localphone
exten => 8611,1,Ringing()
exten => 8611,2,Wait(0.5)
exten => 8611,3,Answer()
exten => 8611,4,Background(/var/lib/asterisk/sounds/en/ivr-prompts)
exten => 8611,5,Wait(2)
exten => 8611,6,Goto(8611,2)

; Sales
exten => 1,1,Goto(context-out,601,1)

; Billing
exten => 2,1,Goto(context-out,602,1)

; Technical Support
exten => 3,1,Goto(context-out,603,1)

; Operator
exten => 4,1,Goto(context-out,604,1)

; General voicemail box
exten => 5,1,VoiceMail(650@voicemail-context,s,u)
exten => 5,n,Hangup()

; If you dial 7, you can leave a message in the CEO's voicemail box
exten => 7,1,VoiceMail(631@voicemail-context,s,u)
exten => 7,n,Hangup()

; If you dial 8, you can leave a message in the CTO's voicemail box
exten => 8,1,VoiceMail(632@voicemail-context,s,u)
exten => 8,n,Hangup()


[textmessages]

autohints = yes

exten => 601,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 602,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 603,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 604,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 631,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 632,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

From a phone connected to the Asterisk server configured as above, if you want to make a call to an external number using a Telnyx account, add a 9 in front of the receiver’s number; if you want to use Localphone, add an 8 in front of the receiver’s number. The country calling code must be added after 9 or 8 and then the actual number. For example, if you want to call the German phone number 5050505050 with Telnyx, you’ll have to dial:

9495050505050

where 49 is the country calling code of Germany. The ‘+’ sign or 00, which are usually written in front of the country calling code have to be ignored.

Please note that 8611 is the extension to which you configured all calls to be forwarded to in your localphone.com account (if you use Localphone), as described in the Acquire a real phone number from Localphone and configure a localphone.com account chapter, and 12020202020 is the real phone number bought from Telnyx (if you use Telnyx), configured as described in the Acquire a real phone number from Telnyxand and configure a telnyx.com account chapter.

The following block:

; Read voicemail messages
exten => 955,1,Answer(500)
exten => 955,n,VoiceMailMain(@voicemail-context)

indicates that when you want to listen to the voicemail messages for a particular extension, you have to dial 955 (on a browser phone/softphone/hardphone connected to Asterik). The call will be answered by the default Asterisk voicemail service which is called ‘Comedian Mail’. The virtual operator will ask ‘mailbox ?’ at which point you will have to enter the extension number for which you want to check the voicemail messages (Eg. 601); then it will ask ‘password ?’ at which point you will have to enter the password set up for that extension’s voicemail box in the /etc/asterisk/voicemail.conf file. After the extension number and password are accepted, you can listen to the new or old messages, transfer messages to another extension, delete messages, etc. by pressing different keys, as instructed by the virtual operator.

While listening to the IVR prompts, the caller can go directly to the operator by pressing 4, to the general voicemail box by pressing 5, to the CEO’s voicemail by pressing 7 or to the CTO’s voicemail by pressing 8. The caller has the same options while being on hold in a queue. As it has been set up in the configurations from above, the on hold music will last for a maximum of 20 minutes.

A user connected to Asterisk can also listen to the voicemail messages from any voicemail box, by dialing 955 and then entering the number of the extension followed by its password (if (s)he knows the password).

Please note that the ‘classic’ way of making calls to outside numbers, as opposed to making calls to internal extensions, is by adding a digit, such as 9, in front of the dialed numbers. In this way you can make calls to outside numbers using multiple phone numbers acquired from the same SIP provider or from different SIP providers. For example, to make a call to an outside number using a number from Telnyx you can add a 9 in front of the outside number, as exemplified above, to make a call using a Localphone number to an outside number you can add an 8, to make a call using a number from a third SIP provider you can add a 7, etc. It’s important to note that when you make or receive calls, Asterisk will try to match the most specific extension configured in the dial plan. For example, by this line:

exten => _9.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)

you tell Asterisk that when the dialed number starts with the digit 9 followed by something else, it should remove the first digit (${EXTEN:1}) then route the call through the Telnyx account, ring for 60 seconds, produce a ringing tone while ringing (r), and allow the called party to transfer the call (t). If you also have this line in the dial plan:

exten => 955,1,Answer(500)

when you dial 955, Asterisk will act as it should, directing the call to extension 500, which is the default extension for the voicemail voice menu. It will not remove the first digit from 955, although it starts with the digit 9 and the other line mentioned above instructs Asterisk to remove the first digit from all dialed numbers that start with 9. This happens because 955 is more specific than _9. , so Asterisk will know that in the case of 955, the first digit shouldn’t be removed and the call shouldn’t be routed through the Telnyx account, but directed to extension 500.

However, if you want to implement a more ‘comfortable’ dial plan, where you won’t have to remember to add a digit to call outside numbers, instead of these two blocks from the [context-out] context:

; Dial external numbers with Telnyx
exten => _9.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)
exten => _9.,2,Answer()
exten => _9.,3,Hangup()

; Dial external numbers with Localphone
exten => _8.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _8.,2,Answer()
exten => _8.,3,Hangup()

you can enter the following blocks:

; If the dialed number starts with a '+', remove the '+' sign
exten => _+X.,1,Goto(${EXTEN:1}, 1)

; If the dialed number is 3 digits long, dial an extension. If the number is 4 digits or more in length, dial an outside number using a Telnyx SIP account
exten => _X.,1,GotoIf($[${LEN($EXTEN)} > 3]?morethanthree:lessthanfour)
exten => _X.,n(lessthanfour),Goto(${EXTEN},1)
exten => _X.,n(morethanthree),Dial(PJSIP/${EXTEN}@telnyx,60,tr)
exten => _X.,n,Answer()
exten => _X.,n,Hangup()

; If the dialed number starts with a '#' sign, dial an outside number using a Localphone SIP account
exten => _#X.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _#X.,n,Answer()
exten => _#X.,n,Hangup()

By using the three blocks from above, you will have the following benefits:

  • If you accidentally add the ‘+’ sign in front of the country calling code, it will be automatically removed.

  • When calling external numbers, you won’t have to remember to add an extra digit in front of them. If the dialed number is three digits (or less) in length, Asterisk will treat it as an internal extension; if the dialed number is 4 digits or more in length, Asterisk will treat it as an external number. The call to such numbers will be automatically routed through the Telnyx account. To be able to also use a Localphone account to call outside numbers, you will add a hash (#) in front of them. In this way, when you want to call any phone number, be it an internal extension or an outside number, you will just dial that number and call. Only when you want to call outside numbers using a secondary SIP account, you will add a hash in front of them. Of course, you can replace Telnyx with Localphone, so that you make all your ‘regular’ calls to outside numbers using Localphone and make ‘exceptional’ calls to outside numbers with Telnyx.

In the third block from above, you can replace the hash (#) with a digit like 9, 8, 7, etc.

Please note, if you want to be able to call emergency services from a phone number acquired from Telnyx (Localphone numbers cannot be used to call emergency services), you’ll have to enable calling emergency services in your Telnyx account (click on ‘Numbers’ on the left sidebar, click on the wheel icon on the row of the phone number, click on the ‘Emergency’ tab, check the ‘Emergency services enabled’ checkbox), then you’ll have to add a block inside the [context-out] context, similar to the following:

; Dial the 911 US emergency number
exten => 911,1,Dial(PJSIP/${EXTEN}@telnyx,60,tr)
exten => 911,2,Answer()
exten => 911,3,Hangup()

Of course, if you live in Europe or in countries who have adopted the 112 emergency number, the block will look like this:

; Dial the 112 emergency number
exten => 112,1,Dial(PJSIP/${EXTEN}@telnyx,60,tr)
exten => 112,2,Answer()
exten => 112,3,Hangup()

Please also note that by default, Asterisk is configured to allow calls with a maximum duration of 10800 seconds (3 hours). If you want to disable this limitation, open the /etc/asterisk/extensions.conf file:

nano /etc/asterisk/extensions.conf

Search for the following line:

same => n,Set(TIMEOUT(absolute)=10800)

Change it to make it look like this:

same => n,Set(TIMEOUT(absolute)=0)

Of course, instead of disabling this limit, you can set a different limit. For example, for a maximum call duration of 10 hours, you will set the TIMEOUT(absolute) parameter to 36000. Restart Asterisk:

systemctl restart asterisk

25.13.7.2. The second scenario

All incoming calls are directed to one extension, the extension of a human operator/secretary/office assistant who picks up and then transfers any call to the extension that the caller needs. If the operator’s extension is in use, the caller is put on hold, in a queue. If it’s disconnected, the caller is sent to the general voicemail box. Also, when the operator transfers the call, if the extension to which the call is transferred is in use, the caller is put on hold in a queue, if the extension is disconnected, the caller is sent to that extension’s voicemail box.

For this scenario enter the following lines at the bottom of the /etc/asterisk/extensions.conf file:

[context-out]

autohints = yes

; Dial external numbers with Telnyx
exten => _9.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)
exten => _9.,2,Answer()
exten => _9.,3,Hangup()

; Dial external numbers with Localphone
exten => _8.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _8.,2,Answer()
exten => _8.,3,Hangup()

; Sales Department
exten => 601,1,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/601)} = UNKNOWN]]?601,2:601,4)
exten => 601,2,VoiceMail(601@voicemail-context,s,u)
exten => 601,3,Hangup()
exten => 601,4,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = INUSE] | [${DEVICE_STATE(PJSIP/601)} = BUSY] | [${DEVICE_STATE(PJSIP/601)} = ONHOLD] | [${DEVICE_STATE(PJSIP/601)} = RINGING]]?601,5:601,8)
exten => 601,5,Answer()
exten => 601,6,Queue(sales-queue,nt,,,1200)
exten => 601,7,Hangup()
exten => 601,8,Dial(PJSIP/601,60)
exten => 601,9,Hangup()

; Billing Department
exten => 602,1,GotoIf($[[${DEVICE_STATE(PJSIP/602)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/602)} = UNKNOWN]]?602,2:602,4)
exten => 602,2,VoiceMail(602@voicemail-context,s,u)
exten => 602,3,Hangup()
exten => 602,4,GotoIf($[[${DEVICE_STATE(PJSIP/602)} = INUSE] | [${DEVICE_STATE(PJSIP/602)} = BUSY] | [${DEVICE_STATE(PJSIP/602)} = ONHOLD] | [${DEVICE_STATE(PJSIP/602)} = RINGING]]?602,5:602,8)
exten => 602,5,Answer()
exten => 602,6,Queue(billing-queue,nt,,,1200)
exten => 602,7,Hangup()
exten => 602,8,Dial(PJSIP/602,60)
exten => 602,9,Hangup()

; Technical Support Department
exten => 603,1,GotoIf($[[${DEVICE_STATE(PJSIP/603)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/603)} = UNKNOWN]]?603,2:603,4)
exten => 603,2,VoiceMail(603@voicemail-context,s,u)
exten => 603,3,Hangup()
exten => 603,4,GotoIf($[[${DEVICE_STATE(PJSIP/603)} = INUSE] | [${DEVICE_STATE(PJSIP/603)} = BUSY] | [${DEVICE_STATE(PJSIP/603)} = ONHOLD] | [${DEVICE_STATE(PJSIP/603)} = RINGING]]?603,5:603,8)
exten => 603,5,Answer()
exten => 603,6,Queue(techsupport-queue,nt,,,1200)
exten => 603,7,Hangup()
exten => 603,8,Dial(PJSIP/603,60)
exten => 603,9,Hangup()

; Operator
exten => 604,1,GotoIf($[[${DEVICE_STATE(PJSIP/604)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/604)} = UNKNOWN]]?604,2:604,4)
exten => 604,2,VoiceMail(650@voicemail-context,s,u)
exten => 604,3,Hangup()
exten => 604,4,GotoIf($[[${DEVICE_STATE(PJSIP/604)} = INUSE] | [${DEVICE_STATE(PJSIP/604)} = BUSY] | [${DEVICE_STATE(PJSIP/604)} = ONHOLD] | [${DEVICE_STATE(PJSIP/604)} = RINGING]]?604,5:604,8)
exten => 604,5,Answer()
exten => 604,6,Queue(operator-queue,nt,,,1200)
exten => 604,7,Hangup()
exten => 604,8,Dial(PJSIP/604,60)
exten => 604,9,Hangup()

; CEO's extension
exten => 631,1,GotoIf($[[${DEVICE_STATE(PJSIP/631)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/631)} = UNKNOWN]]?631,2:631,4)
exten => 631,2,VoiceMail(631@voicemail-context,s,u)
exten => 631,3,Hangup()
exten => 631,4,GotoIf($[[${DEVICE_STATE(PJSIP/631)} = INUSE] | [${DEVICE_STATE(PJSIP/631)} = BUSY] | [${DEVICE_STATE(PJSIP/631)} = ONHOLD] | [${DEVICE_STATE(PJSIP/631)} = RINGING]]?631,5:631,8)
exten => 631,5,Answer()
exten => 631,6,Queue(ceo-queue,nt,,,1200)
exten => 631,7,Hangup()
exten => 631,8,Dial(PJSIP/631,60)
exten => 631,9,Hangup()

; CTO's extension
exten => 632,1,GotoIf($[[${DEVICE_STATE(PJSIP/632)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/632)} = UNKNOWN]]?632,2:632,4)
exten => 632,2,VoiceMail(632@voicemail-context,s,u)
exten => 632,3,Hangup()
exten => 632,4,GotoIf($[[${DEVICE_STATE(PJSIP/632)} = INUSE] | [${DEVICE_STATE(PJSIP/632)} = BUSY] | [${DEVICE_STATE(PJSIP/632)} = ONHOLD] | [${DEVICE_STATE(PJSIP/632)} = RINGING]]?632,5:632,8)
exten => 632,5,Answer()
exten => 632,6,Queue(cto-queue,nt,,,1200)
exten => 632,7,Hangup()
exten => 632,8,Dial(PJSIP/632,60)
exten => 632,9,Hangup()

; Operator
exten => 4,1,Goto(604,1)

; If you dial 5, you can leave a message in the general voicemail box
exten => 5,1,VoiceMail(650@voicemail-context,s,u)
exten => 5,n,Hangup()

; If you dial 7, you can leave a message in the CEO's voicemail box
exten => 7,1,VoiceMail(631@voicemail-context,s,u)
exten => 7,n,Hangup()

; If you dial 8, you can leave a message in the CTO's voicemail box
exten => 8,1,VoiceMail(632@voicemail-context,s,u)
exten => 8,n,Hangup()

; Read voicemail messages
exten => 955,1,Answer(500)
exten => 955,n,VoiceMailMain(@voicemail-context)


[context-in]

autohints = yes

; All incoming calls are directed to the operator's extension, if you use Telnyx
exten => 12020202020,1,Goto(context-out,604,1)

; All incoming calls are directed to the operator's extension, if you use Localphone
exten => 8611,1,Goto(context-out,604,1)

; Operator
exten => 4,1,Goto(context-out,604,1)

; general voicemail box
exten => 5,1,VoiceMail(650@voicemail-context,s,u)
exten => 5,n,Hangup()

; If you dial 7, you can leave a message in the CEO's voicemail box
exten => 7,1,VoiceMail(631@voicemail-context,s,u)
exten => 7,n,Hangup()

; If you dial 8, you can leave a message in the CTO's voicemail box
exten => 8,1,VoiceMail(632@voicemail-context,s,u)
exten => 8,n,Hangup()


[textmessages]

autohints = yes

exten => 601,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 602,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 603,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 604,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 631,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 632,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

Please note that 8611 is the extension to which you configured all calls to be forwarded to in your localphone.com account (if you use Localphone), as described in the Acquire a real phone number from Localphone and configure a localphone.com account chapter, and 12020202020 is the real phone number bought from Telnyx (if you use Telnyx), configured as described in the Acquire a real phone number from Telnyx and configure a telnyx.com account chapter.

In this scenario, the general voicemail box message has to begin with a greeting like “Hello, thank you for calling Global Weasels LLC. At the moment no one is available to take your call, but if you leave your name, phone number … etc.”

From a phone connected to the Asterisk server configured as above, if you want to make a call to an external number using Telnyx, you will have to add a 9 in front of the number; if you want to make a call to an external number using Localphone you will have to add an 8 in front of the number. After 9 or 8 you’ll have to enter the country calling code and then the actual number.

While on hold in a queue (the on hold music and messages last for a maximum of 20 minutes), a caller can return to the operator by pressing 4, can leave a message in the general voicemail box by pressing 5, can go the CEO’s voicemail by pressing 7 or to the CTO’s voicemail by pressing 8.

From a phone connected to the Asterisk server, a user can listen to the voicemail messages in a voicemail box, by dialing 955 and then entering the number of the extension followed by its password.

Please note that the ‘classic’ way of making calls to outside numbers, as opposed to making calls to internal extensions, is by adding a digit, such as 9, in front of the dialed numbers. In this way you can make calls to outside numbers using multiple phone numbers acquired from the same SIP provider or from different SIP providers. For example, to make a call to an outside number using a number from Telnyx you can add a 9 in front of the outside number, as exemplified above, to make a call using a Localphone number to an outside number you can add an 8, to make a call using a number from a third SIP provider you can add a 7, etc. It’s important to note that when you make or receive calls, Asterisk will try to match the most specific extension configured in the dial plan. For example, by this line:

exten => _9.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)

you tell Asterisk that when the dialed number starts with the digit 9 followed by something else, it should remove the first digit (${EXTEN:1}) then route the call through the Telnyx account, ring for 60 seconds, produce a ringing tone while ringing (r), and allow the called party to transfer the call (t). If you also have this line in the dial plan:

exten => 955,1,Answer(500)

when you dial 955, Asterisk will act as it should, directing the call to extension 500, which is the default extension for the voicemail voice menu. It will not remove the first digit from 955, although it starts with the digit 9 and the other line mentioned above instructs Asterisk to remove the first digit from all dialed numbers that start with 9. This happens because 955 is more specific than _9. , so Asterisk will know that in the case of 955, the first digit shouldn’t be removed and the call shouldn’t be routed through the Telnyx account, but directed to extension 500.

However, if you want to implement a more ‘comfortable’ dial plan, where you won’t have to remember to add a digit to call outside numbers, instead of these two blocks from the [context-out] context:

; Dial external numbers with Telnyx
exten => _9.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)
exten => _9.,2,Answer()
exten => _9.,3,Hangup()

; Dial external numbers with Localphone
exten => _8.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _8.,2,Answer()
exten => _8.,3,Hangup()

you can enter the following blocks:

; If the dialed number starts with a '+', remove the '+' sign
exten => _+X.,1,Goto(${EXTEN:1}, 1)

; If the dialed number is 3 digits long, dial an extension. If the number is 4 digits or more in length, dial an outside number using a Telnyx SIP account
exten => _X.,1,GotoIf($[${LEN($EXTEN)} > 3]?morethanthree:lessthanfour)
exten => _X.,n(lessthanfour),Goto(${EXTEN},1)
exten => _X.,n(morethanthree),Dial(PJSIP/${EXTEN}@telnyx,60,tr)
exten => _X.,n,Answer()
exten => _X.,n,Hangup()

; If the dialed number starts with a '#' sign, dial an outside number using a Localphone SIP account
exten => _#X.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _#X.,n,Answer()
exten => _#X.,n,Hangup()

By using the three blocks from above, you will have the following benefits:

  • If you accidentally add the ‘+’ sign in front of the country calling code, it will be automatically removed.

  • When calling external numbers, you won’t have to remember to add an extra digit in front of them. If the dialed number is three digits (or less) in length, Asterisk will treat it as an internal extension; if the dialed number is 4 digits or more in length, Asterisk will treat it as an external number. The call to such numbers will be automatically routed through the Telnyx account. To be able to also use a Localphone account to call outside numbers, you will add a hash (#) in front of them. In this way, when you want to call any phone number, be it an internal extension or an outside number, you will just dial that number and call. Only when you want to call outside numbers using a secondary SIP account, you will add a hash in front of them. Of course, you can replace Telnyx with Localphone, so that you make all your ‘regular’ calls to outside numbers using Localphone and make ‘exceptional’ calls to outside numbers with Telnyx.

In the third block from above, you can replace the hash (#) with a digit like 9, 8, 7, etc.

Please note, if you want to be able to call emergency services from a phone number acquired from Telnyx (Localphone numbers cannot be used to call emergency services), you’ll have to enable calling emergency services in your Telnyx account (click on ‘Numbers’ on the left sidebar, click on the wheel icon on the row of the phone number, click on the ‘Emergency’ tab, check the ‘Emergency services enabled’ checkbox), then you’ll have to add a block inside the [context-out] context, similar to the following:

; Dial the 911 US emergency number
exten => 911,1,Dial(PJSIP/${EXTEN}@telnyx,60,tr)
exten => 911,2,Answer()
exten => 911,3,Hangup()

Of course, if you live in Europe or in countries who have adopted the 112 emergency number, the block will look like this:

; Dial the 112 emergency number
exten => 112,1,Dial(PJSIP/${EXTEN}@telnyx,60,tr)
exten => 112,2,Answer()
exten => 112,3,Hangup()

Please also note that by default, Asterisk is configured to allow calls with a maximum duration of 10800 seconds (3 hours). If you want to disable this limitation, open the /etc/asterisk/extensions.conf file:

nano /etc/asterisk/extensions.conf

Search for the following line:

same => n,Set(TIMEOUT(absolute)=10800)

Change it to make it look like this:

same => n,Set(TIMEOUT(absolute)=0)

Of course, instead of disabling this limit, you can set a different limit. For example, for a maximum call duration of 10 hours, you will set the TIMEOUT(absolute) parameter to 36000. Restart Asterisk:

systemctl restart asterisk

25.13.7.3. The third scenario

All incoming calls are directed to all the extensions of the company so that all the phones ring simultaneously and once someone picks up a phone, all the other connections are dropped. If all the extensions are in use, the caller is put on hold, in a queue. If all the extensions are disconnected, the caller is sent to the general voicemail box. This type of dial plan can be used in situations where there is no ‘sales’ phone, or ‘billing’ phone, or ‘technical support’ phone, etc. but all phones have the same function, and it doesn’t matter who is picking up as long as someone picks up. This is because the company is very small, or it doesn’t need phones with specialized functions.

For this scenario enter the following lines at the bottom of the /etc/asterisk/extensions.conf file:

[context-out]

autohints = yes

; Dial external numbers with Localphone
exten => _9.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _9.,2,Answer()
exten => _9.,3,Hangup()

; Dial external numbers with Telnyx
exten => _8.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)
exten => _8.,2,Answer()
exten => _8.,3,Hangup()

; Sales Department
exten => 601,1,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/601)} = UNKNOWN]]?601,2:601,4)
exten => 601,2,VoiceMail(601@voicemail-context,s,u)
exten => 601,3,Hangup()
exten => 601,4,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = INUSE] | [${DEVICE_STATE(PJSIP/601)} = BUSY] | [${DEVICE_STATE(PJSIP/601)} = ONHOLD] | [${DEVICE_STATE(PJSIP/601)} = RINGING]]?601,5:601,8)
exten => 601,5,Answer()
exten => 601,6,Queue(sales-queue,nt,,,1200)
exten => 601,7,Hangup()
exten => 601,8,Dial(PJSIP/601,60)
exten => 601,9,Hangup()

; Billing Department
exten => 602,1,GotoIf($[[${DEVICE_STATE(PJSIP/602)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/602)} = UNKNOWN]]?602,2:602,4)
exten => 602,2,VoiceMail(602@voicemail-context,s,u)
exten => 602,3,Hangup()
exten => 602,4,GotoIf($[[${DEVICE_STATE(PJSIP/602)} = INUSE] | [${DEVICE_STATE(PJSIP/602)} = BUSY] | [${DEVICE_STATE(PJSIP/602)} = ONHOLD] | [${DEVICE_STATE(PJSIP/602)} = RINGING]]?602,5:602,8)
exten => 602,5,Answer()
exten => 602,6,Queue(billing-queue,nt,,,1200)
exten => 602,7,Hangup()
exten => 602,8,Dial(PJSIP/602,60)
exten => 602,9,Hangup()

; Technical Support Department
exten => 603,1,GotoIf($[[${DEVICE_STATE(PJSIP/603)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/603)} = UNKNOWN]]?603,2:603,4)
exten => 603,2,VoiceMail(603@voicemail-context,s,u)
exten => 603,3,Hangup()
exten => 603,4,GotoIf($[[${DEVICE_STATE(PJSIP/603)} = INUSE] | [${DEVICE_STATE(PJSIP/603)} = BUSY] | [${DEVICE_STATE(PJSIP/603)} = ONHOLD] | [${DEVICE_STATE(PJSIP/603)} = RINGING]]?603,5:603,8)
exten => 603,5,Answer()
exten => 603,6,Queue(techsupport-queue,nt,,,1200)
exten => 603,7,Hangup()
exten => 603,8,Dial(PJSIP/603,60)
exten => 603,9,Hangup()

; Operator
exten => 604,1,GotoIf($[[${DEVICE_STATE(PJSIP/604)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/604)} = UNKNOWN]]?604,2:604,4)
exten => 604,2,VoiceMail(604@voicemail-context,s,u)
exten => 604,3,Hangup()
exten => 604,4,GotoIf($[[${DEVICE_STATE(PJSIP/604)} = INUSE] | [${DEVICE_STATE(PJSIP/604)} = BUSY] | [${DEVICE_STATE(PJSIP/604)} = ONHOLD] | [${DEVICE_STATE(PJSIP/604)} = RINGING]]?604,5:604,8)
exten => 604,5,Answer()
exten => 604,6,Queue(operator-queue,nt,,,1200)
exten => 604,7,Hangup()
exten => 604,8,Dial(PJSIP/604,60)
exten => 604,9,Hangup()

; CEO's extension
exten => 631,1,GotoIf($[[${DEVICE_STATE(PJSIP/631)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/631)} = UNKNOWN]]?631,2:631,4)
exten => 631,2,VoiceMail(631@voicemail-context,s,u)
exten => 631,3,Hangup()
exten => 631,4,GotoIf($[[${DEVICE_STATE(PJSIP/631)} = INUSE] | [${DEVICE_STATE(PJSIP/631)} = BUSY] | [${DEVICE_STATE(PJSIP/631)} = ONHOLD] | [${DEVICE_STATE(PJSIP/631)} = RINGING]]?631,5:631,8)
exten => 631,5,Answer()
exten => 631,6,Queue(ceo-queue,nt,,,1200)
exten => 631,7,Hangup()
exten => 631,8,Dial(PJSIP/631,60)
exten => 631,9,Hangup()

; CTO's extension
exten => 632,1,GotoIf($[[${DEVICE_STATE(PJSIP/632)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/632)} = UNKNOWN]]?632,2:632,4)
exten => 632,2,VoiceMail(632@voicemail-context,s,u)
exten => 632,3,Hangup()
exten => 632,4,GotoIf($[[${DEVICE_STATE(PJSIP/632)} = INUSE] | [${DEVICE_STATE(PJSIP/632)} = BUSY] | [${DEVICE_STATE(PJSIP/632)} = ONHOLD] | [${DEVICE_STATE(PJSIP/632)} = RINGING]]?632,5:632,8)
exten => 632,5,Answer()
exten => 632,6,Queue(cto-queue,nt,,,1200)
exten => 632,7,Hangup()
exten => 632,8,Dial(PJSIP/632,60)
exten => 632,9,Hangup()

; If you dial 5, you can leave a message in the general voicemail box
exten => 5,1,VoiceMail(650@voicemail-context,s,u)
exten => 5,n,Hangup()

; If you dial 7, you can leave a message in the CEO's voicemail box
exten => 7,1,VoiceMail(631@voicemail-context,s,u)
exten => 7,n,Hangup()

; If you dial 8, you can leave a message in the CTO's voicemail box
exten => 8,1,VoiceMail(632@voicemail-context,s,u)
exten => 8,n,Hangup()

; Read voicemail messages
exten => 955,1,Answer(500)
exten => 955,n,VoiceMailMain(@voicemail-context)


[context-in]

autohints = yes

; All incoming calls are directed to all the phones, if you use Telnyx
exten => 12020202020,1,Ringing()
exten => 12020202020,2,Wait(0.5)
exten => 12020202020,3,Answer()
exten => 12020202020,4,GotoIf($[[[${DEVICE_STATE(PJSIP/601)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/601)} = UNKNOWN]] & [[${DEVICE_STATE(PJSIP/602)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/602)} = UNKNOWN]] & [[${DEVICE_STATE(PJSIP/603)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/603)} = UNKNOWN]] & [[${DEVICE_STATE(PJSIP/604)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/604)} = UNKNOWN]] & [[${DEVICE_STATE(PJSIP/631)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/631)} = UNKNOWN]] & [[${DEVICE_STATE(PJSIP/632)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/632)} = UNKNOWN]]]?12020202020,5:12020202020,7)
exten => 12020202020,5,VoiceMail(650@voicemail-context,s,u)
exten => 12020202020,6,Hangup()
exten => 12020202020,7,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = NOT_INUSE] | [${DEVICE_STATE(PJSIP/602)} = NOT_INUSE] | [${DEVICE_STATE(PJSIP/603)} = NOT_INUSE] | [${DEVICE_STATE(PJSIP/604)} = NOT_INUSE] | [${DEVICE_STATE(PJSIP/631)} = NOT_INUSE] | [${DEVICE_STATE(PJSIP/632)} = NOT_INUSE]]?12020202020,8:12020202020,10)
exten => 12020202020,8,Queue(general-queue,nrt,,,1200)
exten => 12020202020,9,Hangup()
exten => 12020202020,10,Queue(general-queue,nt,,,1200)
exten => 12020202020,11,Hangup()

; All incoming calls are directed to all the phones, if you use Localphone
exten => 8611,1,Ringing()
exten => 8611,2,Wait(0.5)
exten => 8611,3,Answer()
exten => 8611,4,GotoIf($[[[${DEVICE_STATE(PJSIP/601)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/601)} = UNKNOWN]] & [[${DEVICE_STATE(PJSIP/602)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/602)} = UNKNOWN]] & [[${DEVICE_STATE(PJSIP/603)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/603)} = UNKNOWN]] & [[${DEVICE_STATE(PJSIP/604)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/604)} = UNKNOWN]] & [[${DEVICE_STATE(PJSIP/631)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/631)} = UNKNOWN]] & [[${DEVICE_STATE(PJSIP/632)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/632)} = UNKNOWN]]]?8611,5:8611,7)
exten => 8611,5,VoiceMail(650@voicemail-context,s,u)
exten => 8611,6,Hangup()
exten => 8611,7,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = NOT_INUSE] | [${DEVICE_STATE(PJSIP/602)} = NOT_INUSE] | [${DEVICE_STATE(PJSIP/603)} = NOT_INUSE] | [${DEVICE_STATE(PJSIP/604)} = NOT_INUSE] | [${DEVICE_STATE(PJSIP/631)} = NOT_INUSE] | [${DEVICE_STATE(PJSIP/632)} = NOT_INUSE]]?8611,8:8611,10)
exten => 8611,8,Queue(general-queue,nrt,,,1200)
exten => 8611,9,Hangup()
exten => 8611,10,Queue(general-queue,nt,,,1200)
exten => 8611,11,Hangup()

; general voicemail box
exten => 5,1,VoiceMail(650@voicemail-context,s,u)
exten => 5,n,Hangup()


[textmessages]

autohints = yes

exten => 601,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 602,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 603,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 604,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 631,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 632,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

Please note that 8611 is the extension to which you configured all calls to be forwarded to in your localphone.com account (if you use Localphone), as described in the Acquire a real phone number from Localphone and configure a localphone.com account chapter, and 12020202020 is the real phone number bought from Telnyx (if you use Telnyx), configured as described in the Acquire a real phone number from Telnyx and configure a telnyx.com account chapter.

For this scenario you have to edit the /etc/asterisk/queues.conf file:

nano /etc/asterisk/queues.conf

At the bottom of this file, right below the [cto-queue] block, add the following block:

[general-queue]

context=context-in
musicclass=onhold-general
strategy=ringall
retry=4
timeout=1200
announce-holdtime=no
announce-frequency=0
announce-position=no
joinempty=yes
leavewhenempty=no
ringinuse=no
autofill=no
maxlen=0
memberdelay=0
wrapuptime=0
weight=0
member => PJSIP/601
member => PJSIP/602
member => PJSIP/603
member => PJSIP/604
member => PJSIP/631
member => PJSIP/632

From a phone connected to the Asterisk server configured as above, if you want to make a call to an external number using Telnyx, you will have to add a 9 in front of the number; if you want to make a call to an external number using Localphone, you will have to add an 8 in front of the number. After 9 or 8 you’ll have to enter the country calling code and then the actual number.

If all the phones are unavailable (disconnected), the caller is sent to the general voicemail box. If all the phones are busy, the caller is put on hold in the general queue (the on hold music will last for a maximum of 20 minutes). From there he can press 5 to go to the general voicemail box, but he cannot return to the operator by pressing 4. This should be reflected in the on hold intermittent messages, so that the caller knows what are his options while holding. He has to wait in line until at least one phone becomes available.

If when someone calls, at least one phone is available (while all the others are busy or unavailable), the caller is put on hold in the general queue, but he won’t hear the on hold music and messages. Instead he will hear the available phone ringing.

From a phone connected to the Asterisk server, a user can listen to the voicemail messages in a voicemail box, by dialing 955 and then entering the number of the extension followed by its password.

Please note that the ‘classic’ way of making calls to outside numbers, as opposed to making calls to internal extensions, is by adding a digit, such as 9, in front of the dialed numbers. In this way you can make calls to outside numbers using multiple phone numbers acquired from the same SIP provider or from different SIP providers. For example, to make a call to an outside number using a number from Telnyx you can add a 9 in front of the outside number, as exemplified above, to make a call using a Localphone number to an outside number you can add an 8, to make a call using a number from a third SIP provider you can add a 7, etc. It’s important to note that when you make or receive calls, Asterisk will try to match the most specific extension configured in the dial plan. For example, by this line:

exten => _9.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)

you tell Asterisk that when the dialed number starts with the digit 9 followed by something else, it should remove the first digit (${EXTEN:1}) then route the call through the Telnyx account, ring for 60 seconds, produce a ringing tone while ringing (r), and allow the called party to transfer the call (t). If you also have this line in the dial plan:

exten => 955,1,Answer(500)

when you dial 955, Asterisk will act as it should, directing the call to extension 500, which is the default extension for the voicemail voice menu. It will not remove the first digit from 955, although it starts with the digit 9 and the other line mentioned above instructs Asterisk to remove the first digit from all dialed numbers that start with 9. This happens because 955 is more specific than _9. , so Asterisk will know that in the case of 955, the first digit shouldn’t be removed and the call shouldn’t be routed through the Telnyx account, but directed to extension 500.

However, if you want to implement a more ‘comfortable’ dial plan, where you won’t have to remember to add a digit to call outside numbers, instead of these two blocks from the [context-out] context:

; Dial external numbers with Telnyx
exten => _9.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)
exten => _9.,2,Answer()
exten => _9.,3,Hangup()

; Dial external numbers with Localphone
exten => _8.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _8.,2,Answer()
exten => _8.,3,Hangup()

you can enter the following blocks:

; If the dialed number starts with a '+', remove the '+' sign
exten => _+X.,1,Goto(${EXTEN:1}, 1)

; If the dialed number is 3 digits long, dial an extension. If the number is 4 digits or more in length, dial an outside number using a Telnyx SIP account
exten => _X.,1,GotoIf($[${LEN($EXTEN)} > 3]?morethanthree:lessthanfour)
exten => _X.,n(lessthanfour),Goto(${EXTEN},1)
exten => _X.,n(morethanthree),Dial(PJSIP/${EXTEN}@telnyx,60,tr)
exten => _X.,n,Answer()
exten => _X.,n,Hangup()

; If the dialed number starts with a '#' sign, dial an outside number using a Localphone SIP account
exten => _#X.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _#X.,n,Answer()
exten => _#X.,n,Hangup()

By using the three blocks from above, you will have the following benefits:

  • If you accidentally add the ‘+’ sign in front of the country calling code, it will be automatically removed.

  • When calling external numbers, you won’t have to remember to add an extra digit in front of them. If the dialed number is three digits (or less) in length, Asterisk will treat it as an internal extension; if the dialed number is 4 digits or more in length, Asterisk will treat it as an external number. The call to such numbers will be automatically routed through the Telnyx account. To be able to also use a Localphone account to call outside numbers, you will add a hash (#) in front of them. In this way, when you want to call any phone number, be it an internal extension or an outside number, you will just dial that number and call. Only when you want to call outside numbers using a secondary SIP account, you will add a hash in front of them. Of course, you can replace Telnyx with Localphone, so that you make all your ‘regular’ calls to outside numbers using Localphone and make ‘exceptional’ calls to outside numbers with Telnyx.

In the third block from above, you can replace the hash (#) with a digit like 9, 8, 7, etc.

Please note, if you want to be able to call emergency services from a phone number acquired from Telnyx (Localphone numbers cannot be used to call emergency services), you’ll have to enable calling emergency services in your Telnyx account (click on ‘Numbers’ on the left sidebar, click on the wheel icon on the row of the phone number, click on the ‘Emergency’ tab, check the ‘Emergency services enabled’ checkbox), then you’ll have to add a block inside the [context-out] context, similar to the following:

; Dial the 911 US emergency number
exten => 911,1,Dial(PJSIP/${EXTEN}@telnyx,60,tr)
exten => 911,2,Answer()
exten => 911,3,Hangup()

Of course, if you live in Europe or in countries who have adopted the 112 emergency number, the block will look like this:

; Dial the 112 emergency number
exten => 112,1,Dial(PJSIP/${EXTEN}@telnyx,60,tr)
exten => 112,2,Answer()
exten => 112,3,Hangup()

Please also note that by default, Asterisk is configured to allow calls with a maximum duration of 10800 seconds (3 hours). If you want to disable this limitation, open the /etc/asterisk/extensions.conf file:

nano /etc/asterisk/extensions.conf

Search for the following line:

same => n,Set(TIMEOUT(absolute)=10800)

Change it to make it look like this:

same => n,Set(TIMEOUT(absolute)=0)

Of course, instead of disabling this limit, you can set a different limit. For example, for a maximum call duration of 10 hours, you will set the TIMEOUT(absolute) parameter to 36000. Restart Asterisk:

systemctl restart asterisk

25.13.7.4. The fourth scenario

The company has one external phone number for regular phone calls and all the phone calls to this number are directed towards an IVR and treated as in the first scenario. The company also has a secondary phone number, for the CEO, and all incoming calls to this number are routed directly to the CEO’s phone. If the CEO’s phone is already in use, the caller is put on hold, if the phone is disconnected the caller is sent to the voicemail.

If you use Localphone, since in this situation the company has two real phone numbers, you will have to attach these two numbers to two separate SIP IDs provided by Localphone, so that all the outgoing calls from the CEO will go through one SIP ID and the callees will see the CEO’s number as the ‘From’ number, while all the rest of the employees will make their outgoing calls through the other SIP ID and all the calls coming from them will appear as coming from the company’s general phone number. This implies that you added a second real phone number to your localphone.com account, as described in the Acquire a real phone number from Localphone and configure a localphone.com account chapter.

After buying the second local number, if you still have one single SIP ID in your Localphone account, it’s time to ask for a second SIP ID by contacting technical support at: support@support.localphone.com . After you receive the second SIP ID, you should forward all the calls received by the CEO’s phone number to a special separate extension, let’s say 8631 . Thus, all the calls received by the company’s phone number for general use will be forwarded in your localphone.com account to extension 8611, while all the calls received by the CEO’s phone number will be forwarded to extension 8631 . The way you forward incoming calls to a SIP URI in your localphone.com account has been described in the above mentioned chapter.

If you use Telnyx, the two real phone numbers will be specified in the /etc/asterisk/extensions.conf file as described below.

Next edit the /etc/asterisk/extensions.conf file:

nano /etc/asterisk/extensions.conf

Add the following lines at the bottom of this file:

[context-out]

autohints = yes

; Dial external numbers with Telnyx
exten => _9.,1,Dial(PJSIP/${EXTEN:1}@Telnyx,60,tr)
exten => _9.,2,Answer()
exten => _9.,3,Hangup()

; Dial external numbers with Localphone
exten => _8.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _8.,2,Answer()
exten => _8.,3,Hangup()

; The CEO adds a 3 in front of external numbers when dialing them using Telnyx
exten => _3.,1,Dial(PJSIP/${EXTEN:1}@telnyx2,60,tr)
exten => _3.,2,Hangup()

; The CEO adds a 2 in front of external numbers when dialing them using Localphone
exten => _2.,1,Dial(PJSIP/${EXTEN:1}@localphone2,60,tr)
exten => _2.,2,Hangup()

; Sales Department
exten => 601,1,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/601)} = UNKNOWN]]?601,2:601,4)
exten => 601,2,VoiceMail(601@voicemail-context,s,u)
exten => 601,3,Hangup()
exten => 601,4,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = INUSE] | [${DEVICE_STATE(PJSIP/601)} = BUSY] | [${DEVICE_STATE(PJSIP/601)} = ONHOLD] | [${DEVICE_STATE(PJSIP/601)} = RINGING]]?601,5:601,8)
exten => 601,5,Answer()
exten => 601,6,Queue(sales-queue,nt,,,1200)
exten => 601,7,Hangup()
exten => 601,8,Dial(PJSIP/601,60)
exten => 601,9,Hangup()

; Billing Department
exten => 602,1,GotoIf($[[${DEVICE_STATE(PJSIP/602)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/602)} = UNKNOWN]]?602,2:602,4)
exten => 602,2,VoiceMail(602@voicemail-context,s,u)
exten => 602,3,Hangup()
exten => 602,4,GotoIf($[[${DEVICE_STATE(PJSIP/602)} = INUSE] | [${DEVICE_STATE(PJSIP/602)} = BUSY] | [${DEVICE_STATE(PJSIP/602)} = ONHOLD] | [${DEVICE_STATE(PJSIP/602)} = RINGING]]?602,5:602,8)
exten => 602,5,Answer()
exten => 602,6,Queue(billing-queue,nt,,,1200)
exten => 602,7,Hangup()
exten => 602,8,Dial(PJSIP/602,60)
exten => 602,9,Hangup()

; Technical Support Department
exten => 603,1,GotoIf($[[${DEVICE_STATE(PJSIP/603)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/603)} = UNKNOWN]]?603,2:603,4)
exten => 603,2,VoiceMail(603@voicemail-context,s,u)
exten => 603,3,Hangup()
exten => 603,4,GotoIf($[[${DEVICE_STATE(PJSIP/603)} = INUSE] | [${DEVICE_STATE(PJSIP/603)} = BUSY] | [${DEVICE_STATE(PJSIP/603)} = ONHOLD] | [${DEVICE_STATE(PJSIP/603)} = RINGING]]?603,5:603,8)
exten => 603,5,Answer()
exten => 603,6,Queue(techsupport-queue,nt,,,1200)
exten => 603,7,Hangup()
exten => 603,8,Dial(PJSIP/603,60)
exten => 603,9,Hangup()

; Operator
exten => 604,1,GotoIf($[[${DEVICE_STATE(PJSIP/604)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/604)} = UNKNOWN]]?604,2:604,4)
exten => 604,2,VoiceMail(604@voicemail-context,s,u)
exten => 604,3,Hangup()
exten => 604,4,GotoIf($[[${DEVICE_STATE(PJSIP/604)} = INUSE] | [${DEVICE_STATE(PJSIP/604)} = BUSY] | [${DEVICE_STATE(PJSIP/604)} = ONHOLD] | [${DEVICE_STATE(PJSIP/604)} = RINGING]]?604,5:604,8)
exten => 604,5,Answer()
exten => 604,6,Queue(operator-queue,nt,,,1200)
exten => 604,7,Hangup()
exten => 604,8,Dial(PJSIP/604,60)
exten => 604,9,Hangup()

; CEO's extension
exten => 631,1,GotoIf($[[${DEVICE_STATE(PJSIP/631)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/631)} = UNKNOWN]]?631,2:631,4)
exten => 631,2,VoiceMail(631@voicemail-context,s,u)
exten => 631,3,Hangup()
exten => 631,4,GotoIf($[[${DEVICE_STATE(PJSIP/631)} = INUSE] | [${DEVICE_STATE(PJSIP/631)} = BUSY] | [${DEVICE_STATE(PJSIP/631)} = ONHOLD] | [${DEVICE_STATE(PJSIP/631)} = RINGING]]?631,5:631,8)
exten => 631,5,Answer()
exten => 631,6,Queue(ceo-queue,nt,,,1200)
exten => 631,7,Hangup()
exten => 631,8,Dial(PJSIP/631,60)
exten => 631,9,Hangup()

; CTO's extension
exten => 632,1,GotoIf($[[${DEVICE_STATE(PJSIP/632)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/632)} = UNKNOWN]]?632,2:632,4)
exten => 632,2,VoiceMail(632@voicemail-context,s,u)
exten => 632,3,Hangup()
exten => 632,4,GotoIf($[[${DEVICE_STATE(PJSIP/632)} = INUSE] | [${DEVICE_STATE(PJSIP/632)} = BUSY] | [${DEVICE_STATE(PJSIP/632)} = ONHOLD] | [${DEVICE_STATE(PJSIP/632)} = RINGING]]?632,5:632,8)
exten => 632,5,Answer()
exten => 632,6,Queue(cto-queue,nt,,,1200)
exten => 632,7,Hangup()
exten => 632,8,Dial(PJSIP/632,60)
exten => 632,9,Hangup()

; Go to the operator
exten => 4,1,Goto(604,1)

; If you dial 5, you can leave a message in the general voicemail box
exten => 5,1,VoiceMail(650@voicemail-context,s,u)
exten => 5,n,Hangup()

; If you dial 7, you can leave a message in the CEO's voicemail box
exten => 7,1,VoiceMail(631@voicemail-context,s,u)
exten => 7,n,Hangup()

; If you dial 8, you can leave a message in the CTO's voicemail box
exten => 8,1,VoiceMail(632@voicemail-context,s,u)
exten => 8,n,Hangup()

; Read voicemail messages
exten => 955,1,Answer(500)
exten => 955,n,VoiceMailMain(@voicemail-context)


[context-in]

autohints = yes

; Incoming calls to the CEO's phone number are directed towards extension 631 when using Telnyx
exten => 13030303030,1,Goto(context-out,631,1)

; Incoming calls to the CEO's phone number are directed towards extension 631 when using Localphone
exten => 8631,1,Goto(context-out,631,1)

; IVR in case you use Telnyx
exten => 12020202020,1,Ringing()
exten => 12020202020,1,Ringing()
exten => 12020202020,2,Wait(0.5)
exten => 12020202020,3,Answer()
exten => 12020202020,4,Background(/var/lib/asterisk/sounds/en/ivr-prompts)
exten => 12020202020,5,Wait(2)
exten => 12020202020,6,Goto(12020202020,2)

; IVR in case you use Localphone
exten => 8611,1,Ringing()
exten => 8611,2,Wait(0.5)
exten => 8611,3,Answer()
exten => 8611,4,Background(/var/lib/asterisk/sounds/en/ivr-prompts)
exten => 8611,5,Wait(2)
exten => 8611,6,Goto(8611,2)

; Sales
exten => 1,1,Goto(context-out,601,1)

; Billing
exten => 2,1,Goto(context-out,602,1)

; Technical Support
exten => 3,1,Goto(context-out,603,1)

; Operator
exten => 4,1,Goto(context-out,604,1)

; General voicemail box
exten => 5,1,VoiceMail(650@voicemail-context,s,u)
exten => 5,n,Hangup()

; If you dial 7, you can leave a message in the CEO's voicemail box
exten => 7,1,VoiceMail(631@voicemail-context,s,u)
exten => 7,n,Hangup()

; If you dial 8, you can leave a message in the CTO's voicemail box
exten => 8,1,VoiceMail(632@voicemail-context,s,u)
exten => 8,n,Hangup()


[textmessages]

autohints = yes

exten => 601,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 602,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 603,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 604,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 631,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

exten => 632,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

Please note that 8611 is the extension to which you forwarded all calls received by the company’s phone number for general use, in your localphone.com account (if you use Localphone), as described in the Acquire a real phone number from Localphone and configure a localphone.com account chapter, and 12020202020 is the company’s phone number for general use, bought from Telnyx (if you use Telnyx), configured as described in the Acquire a real phone number from Telnyx and configure a telnyx.com account chapter. As mentioned above, 8631 is the extension to which you forwarded all the calls received by the CEO’s phone number acquired from Localphone (if you use Localphone) and 13030303030 is the CEO’s phone number acquired from Telnyx (if you use Telnyx).

Next, edit the /etc/asterisk/pjsip.conf file:

nano /etc/asterisk/pjsip.conf

If you use Telnyx, add the following lines right below the [telnyx-identify] block:

[telnyx-reg2]
type=registration
transport=transport-udp
outbound_auth=telnyx-auth2
server_uri=sip:sip.telnyx.com:5060
client_uri=sip:telnyxasterisk2@sip.telnyx.com:5060
auth_rejection_permanent=no

[telnyx-auth2]
type=auth
auth_type=userpass
username=telnyxasterisk2
password=v4r?*5Su5J!26!Jz4Y

[telnyx2]
type=aor
contact=sip:telnyxasterisk2@sip.telnyx.com
max_contacts=250

[telnyx2]
type=endpoint
transport=transport-udp
context=context-in
disallow=all
allow=ulaw
allow=alaw
direct_media=no
from_user=13030303030
from_domain=sip.telnyx.com
outbound_auth=telnyx-auth2
aors=telnyx2

[telnyx-identify2]
type=identify
endpoint=telnyx2
match=192.76.120.10
match=64.16.250.10
match=185.246.41.140
match=185.246.41.141

Replace telnyxasterisk2 with the real username of the SIP connection associated with the CEO’s phone number acquired from Telnyx, v4r?*5Su5J!26!Jz4Y with the real password of the telnyxasterisk2 user and 13030303030 with the CEO’s real phone number.

If you use Localphone, add the following lines right below the [localphone] blocks:

[localphone2]
type=registration
transport=transport-udp
outbound_auth=localphone2
client_uri=sip:6543217@localphone.com:5060
server_uri=sip:localphone.com:5060
auth_rejection_permanent=no
contact_user=6543217

[localphone2]
type=auth
auth_type=userpass
username=6543217
password=h74V9tB8d4Q5qR2sD

[localphone2]
type=aor
max_contacts=250
contact=sip:6543217@localphone.com

[localphone2]
type=endpoint
transport=transport-udp
context=context-in
disallow=all
allow=ulaw
allow=alaw
direct_media=no
from_user=6543217
from_domain=localphone.com
outbound_auth=localphone2
aors=localphone2

[localphone2]
type=identify
endpoint=localphone2
match=94.75.247.45
match=95.211.119.240

Replace 6543217 with the second SIP ID from your localphone.com account, and h74V9tB8d4Q5qR2sD with your real password.

The above settings will make a second registration with Telnyx’s servers and with Localphone’s servers, respectively.

In this way the CEO can make all his calls to external numbers by adding a 3 in front of them if using Telnyx or a 2 if using Localphone, and the receivers will see his number as the ‘From’ number, while the rest of the employees will add a 9 or an 8 in front of external numbers and the receivers will see the company’s number for general use as the ‘From’ number.

From a phone connected to the Asterisk server, a user can listen to the voicemail messages in a voicemail box, by dialing 955 and then entering the number of the extension followed by its password.

Please note that the ‘classic’ way of making calls to outside numbers, as opposed to making calls to internal extensions, is by adding a digit, such as 9, in front of the dialed numbers. In this way you can make calls to outside numbers using multiple phone numbers acquired from the same SIP provider or from different SIP providers. For example, to make a call to an outside number using a number from Telnyx you can add a 9 in front of the outside number, as exemplified above, to make a call using a Localphone number to an outside number you can add an 8, to make a call using a number from a third SIP provider you can add a 7, etc. It’s important to note that when you make or receive calls, Asterisk will try to match the most specific extension configured in the dial plan. For example, by this line:

exten => _9.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)

you tell Asterisk that when the dialed number starts with the digit 9 followed by something else, it should remove the first digit (${EXTEN:1}) then route the call through the Telnyx account, ring for 60 seconds, produce a ringing tone while ringing (r), and allow the called party to transfer the call (t). If you also have this line in the dial plan:

exten => 955,1,Answer(500)

when you dial 955, Asterisk will act as it should, directing the call to extension 500, which is the default extension for the voicemail voice menu. It will not remove the first digit from 955, although it starts with the digit 9 and the other line mentioned above instructs Asterisk to remove the first digit from all dialed numbers that start with 9. This happens because 955 is more specific than _9. , so Asterisk will know that in the case of 955, the first digit shouldn’t be removed and the call shouldn’t be routed through the Telnyx account, but directed to extension 500.

However, if you want to implement a more ‘comfortable’ dial plan, where you won’t have to remember to add a digit to call outside numbers, instead of these two blocks from the [context-out] context:

; Dial external numbers with Telnyx
exten => _9.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)
exten => _9.,2,Answer()
exten => _9.,3,Hangup()

; Dial external numbers with Localphone
exten => _8.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _8.,2,Answer()
exten => _8.,3,Hangup()

you can enter the following blocks:

; If the dialed number starts with a '+', remove the '+' sign
exten => _+X.,1,Goto(${EXTEN:1}, 1)

; If the dialed number is 3 digits long, dial an extension. If the number is 4 digits or more in length, dial an outside number using a Telnyx SIP account
exten => _X.,1,GotoIf($[${LEN($EXTEN)} > 3]?morethanthree:lessthanfour)
exten => _X.,n(lessthanfour),Goto(${EXTEN},1)
exten => _X.,n(morethanthree),Dial(PJSIP/${EXTEN}@telnyx,60,tr)
exten => _X.,n,Answer()
exten => _X.,n,Hangup()

; If the dialed number starts with a '#' sign, dial an outside number using a Localphone SIP account
exten => _#X.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _#X.,n,Answer()
exten => _#X.,n,Hangup()

By using the three blocks from above, you will have the following benefits:

  • If you accidentally add the ‘+’ sign in front of the country calling code, it will be automatically removed.

  • When calling external numbers, you won’t have to remember to add an extra digit in front of them. If the dialed number is three digits (or less) in length, Asterisk will treat it as an internal extension; if the dialed number is 4 digits or more in length, Asterisk will treat it as an external number. The call to such numbers will be automatically routed through the Telnyx account. To be able to also use a Localphone account to call outside numbers, you will add a hash (#) in front of them. In this way, when you want to call any phone number, be it an internal extension or an outside number, you will just dial that number and call. Only when you want to call outside numbers using a secondary SIP account, you will add a hash in front of them. Of course, you can replace Telnyx with Localphone, so that you make all your ‘regular’ calls to outside numbers using Localphone and make ‘exceptional’ calls to outside numbers with Telnyx.

In the third block from above, you can replace the hash (#) with a digit like 9, 8, 7, etc.

Please note, if you want to be able to call emergency services from a phone number acquired from Telnyx (Localphone numbers cannot be used to call emergency services), you’ll have to enable calling emergency services in your Telnyx account (click on ‘Numbers’ on the left sidebar, click on the wheel icon on the row of the phone number, click on the ‘Emergency’ tab, check the ‘Emergency services enabled’ checkbox), then you’ll have to add a block inside the [context-out] context, similar to the following:

; Dial the 911 US emergency number
exten => 911,1,Dial(PJSIP/${EXTEN}@telnyx,60,tr)
exten => 911,2,Answer()
exten => 911,3,Hangup()

Of course, if you live in Europe or in countries who have adopted the 112 emergency number, the block will look like this:

; Dial the 112 emergency number
exten => 112,1,Dial(PJSIP/${EXTEN}@telnyx,60,tr)
exten => 112,2,Answer()
exten => 112,3,Hangup()

Please also note that by default, Asterisk is configured to allow calls with a maximum duration of 10800 seconds (3 hours). If you want to disable this limitation, open the /etc/asterisk/extensions.conf file:

nano /etc/asterisk/extensions.conf

Search for the following line:

same => n,Set(TIMEOUT(absolute)=10800)

Change it to make it look like this:

same => n,Set(TIMEOUT(absolute)=0)

Of course, instead of disabling this limit, you can set a different limit. For example, for a maximum call duration of 10 hours, you will set the TIMEOUT(absolute) parameter to 36000. Restart Asterisk:

systemctl restart asterisk

25.14. Hardphone example

If you ever want to connect a hardphone to your Asterisk server, the /etc/asterisk/pjsip.conf settings for it should look like the following:

; Hardphone example

[640]
type=aor
max_contacts=250


[auth640]
type=auth
auth_type=userpass
username=640
password=t1Q2kD5nzV84u5w2

[640]
type=endpoint
context=context-out
message_context=textmessages
aors=640
auth=auth640
transport=transport-udp
disallow=all
allow=ulaw
allow=alaw

direct_media=no
rtp_symmetric=yes
force_rport=yes

dtls_cert_file=/etc/asterisk/keys/asterisk.pem
dtls_private_key=/etc/asterisk/keys/asterisk.key

allow=h263p
allow=h264
allow=vp8

[640]
type=identify
endpoint=640
match=123.123.123.123

You can choose an extension number different from 640 for the hardphone if you prefer. Replace 123.123.123.123 with the public IP of your server and t1Q2kD5nzV84u5w2 with a password for extension 640.

The configurations in the /etc/asterisk/extensions.conf file should look like this:

[context-out]

autohints = yes

; Hardphone example
exten => 640,1,Dial(PJSIP/640)
exten => 640,2,Answer()
exten => 640,3,Hangup()


[textmessages]

autohints = yes

exten => 640,1,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,Hangup()

25.15. Softphone example

If, instead of a hardphone, you want to connect a softphone to your Asterisk server, the settings in /etc/asterisk/pjsip.conf and /etc/asterisk/extensions.conf should be identical to the ones for the hardphone from above. We’ll illustrate below how to configure Jitsi Desktop (not Jitsi Meet) to connect to Asterisk. You can adapt these settings to use them with other softphones.

After you install and launch Jitsi, in the first screen, in the SIP section you should enter a username and a password. Then, in the upper menu click on Tools > Options > Accounts > click on the ‘Add’ button from the bottom of the window, to add a new SIP account; next, in the ‘Add new account’ window, in the ‘Network’ field select ‘SIP’, then click on the ‘Advanced’ button. In the new window, in the ‘SIP id’ field enter the number of the extension, 640 in this example. In the ‘Password’ field enter the extension’s password (it is mentioned in the /etc/asterisk/pjsip.conf file), in the ‘Display name’ field enter a display name that you want to associate with this connection, leave the ‘Remember password’ checkbox checked, then click on the ‘Next’ button.


In the next window fill the fields as shown below, replacing 123.123.123.123 with the public IP address of your server, and 5827 with your custom port for Asterisk connections.


You can leave all the settings on the ‘Security’, ‘Presence’ and ‘Encodings’ tabs as they are. After you fill in all the fields on the ‘Connection’ tab as shown above, click on Next, then click on ‘Sign in’ to connect your Jitsi softphone to your Asterisk server. Then you will be able to make and receive calls using extension 640.

25.16. Configure Fail2ban to protect Asterisk against brute-force attacks

To enable Fail2ban protection against brute-force attacks, edit the /etc/fail2ban/jail.local file:

nano /etc/fail2ban/jail.local

Search for the [asterisk] block and modify it to make it look like this:

[asterisk]

enabled = true
port     = 5827,5060,5061
filter = asterisk
#action   = %(banaction)s[name=%(__name__)s-tcp, port="%(port)s", protocol="tcp", chain="%(chain)s", actname=%(banaction)s-tcp]
#           %(banaction)s[name=%(__name__)s-udp, port="%(port)s", protocol="udp", chain="%(chain)s", actname=%(banaction)s-udp]
#           %(mta)s-whois[name=%(__name__)s, dest="%(destemail)s"]
action = %(action_)s
logpath  = /var/log/asterisk/messages
findtime = 10800
maxretry = 3
bantime = 604800

Replace 5827 with your custom port for Asterisk. Restart Fail2ban:

systemctl restart fail2ban

25.17. Asterisk Command Line Interface (CLI)

To open the Asterisk CLI run:

asterisk -r

To see all the endpoints configured in Asterisk and their state (In use / Not in use / Unavailable) run:

pjsip show endpoints

To verify that Asterisk has successfully registered with Telnyx or Localphone, run:

pjsip show registrations

The result will look similar to this:

<Registration/ServerURI..............................>  <Auth..........>  <Status.......>
==========================================================================================

 localphone/sip:localphone.com:5060                      localphone        Registered      
 telnyx-reg/sip:sip.telnyx.eu:5060                       telnyx-auth       Registered

Asterisk has two classes of messages that can be displayed in command line: ‘verbose’ messages and ‘debug’ messages.

‘Verbose’ messages offer general information about the calls passing through the system and display notices, warnings, and errors. They are intended for system administrators. Once you open the Asterisk CLI with the asterisk -r command, you can set the level of verbosity for ‘verbose’ messages with commands like this:

core set verbose 4

You can set a level of verbosity between 1 and 10 (you can set verbosity levels above 10, but theywill be considered as 10). You can also set the level of verbosity for ‘verbose’ messages by appending the v option to the asterisk -r command. For example, to open the Asterisk CLI with a verbosity level of 3 for ‘verbose’ messages, you should run:

asterisk -rvvv

‘Debug’ messages offer detailed information about Asterisk connections and events to help developers understand what is happening inside Asterisk and why it behaves in a certain way.

To be able to see debug information in command line you will have to edit the /etc/asterisk/logger.conf file. First make a copy of the original file:

cp /etc/asterisk/logger.conf /etc/asterisk/logger.conf_orig

Then open the file:

nano /etc/asterisk/logger.conf

Search for this line:

console => notice,warning,error

Change it to make it look like this:

console => notice,warning,error,debug

Restart Asterisk:

systemctl restart asterisk

Once you open the Asterisk CLI, you can set the level of verbosity for the ‘debug’ messages with commands like this:

core set debug 5

You can set a level of verbosity between 1 and 10 (you can set verbosity levels above 10, but they will be considered as 10).

25.18. Enabling Asterisk detailed logging

If you want to see more detailed information in the Asterisk log in order to debug errors, unexpected behavior, etc. you can edit the /etc/asterisk/logger.conf file. Enter the following line at the bottom of the file:

debugging => debug,notice,warning,error,verbose(7)

The above line will make Asterisk log all the detailed information of the specified types, in the /var/log/asterisk/debugging log, with a verbosity level of 7. You can change ‘debugging’ to a different name, which will become the name of the log file, and you can set any verbose level up to 10.

Restart Asterisk:

systemctl restart asterisk

25.19. Blacklisting phone numbers

If you want to block phone calls from certain phone numbers you can blacklist them. To blacklist a phone number you have to enter it in the blacklist stored in the AstDB database, so that it persists after system reboot. To put a phone number in the blacklist stored in AstDB first open the Asterisk CLI:

asterisk -rv

Then run:

database put blacklist 491212121212 1

where 491212121212 is the phone number, including the country calling code (here the country calling code is 49). If later you want to remove a phone number from the blacklist run:

database del blacklist 491212121212

If at any moment you want to see what numbers are blacklisted, run:

database show blacklist

Next, open /etc/asterisk/extensions.conf:

nano /etc/asterisk/extensions.conf

We’ll show how to add blacklisting to the dial plan for the first scenario described above, but you can add blacklisting in a similar way to any dial plan.

Just edit the [context-in] section of the dial plan for the first scenario, by adding the three lines shown in bold below (and changing the numbers of the steps that follow, from 1 to 2, from 2 to 3, etc.):

[context-in]

autohints = yes

; IVR in case you use Localphone
exten => 8611,1,GotoIf($[${BLACKLIST()}]?blocked,1)
exten => 8611,2,Ringing()
exten => 8611,3,Wait(0.5)
exten => 8611,4,Answer()
exten => 8611,5,Background(/var/lib/asterisk/sounds/en/ivr-prompts)
exten => 8611,6,Wait(2)
exten => 8611,7,Goto(8611,2)

; IVR in case you use Telnyx
exten => 12020202020,1,GotoIf($[${BLACKLIST()}]?blocked,1)
exten => 12020202020,2,Ringing()
exten => 12020202020,3,Wait(0.5)
exten => 12020202020,4,Answer()
exten => 12020202020,5,Background(/var/lib/asterisk/sounds/en/ivr-prompts)
exten => 12020202020,6,Wait(2)
exten => 12020202020,7,Goto(12020202020,2)

exten => blocked,1,Hangup()

; Sales
exten => 1,1,Goto(context-out,601,1)

; Billing
exten => 2,1,Goto(context-out,602,1)

; Technical Support
exten => 3,1,Goto(context-out,603,1)

; Operator
exten => 4,1,Goto(context-out,604,1)

; General voicemail box
exten => 5,1,VoiceMail(650@voicemail-context,s,u)
exten => 5,n,Hangup()

; If you dial 7, you can leave a message in the CEO's voicemail box
exten => 7,1,VoiceMail(631@voicemail-context,s,u)
exten => 7,n,Hangup()

; If you dial 8, you can leave a message in the CTO's voicemail box
exten => 8,1,VoiceMail(632@voicemail-context,s,u)
exten => 8,n,Hangup()

In this way, all the incoming calls to your Localphone or Telnyx number are directed to your Asterisk server and here, before any action, the caller’s phone number is checked against the blacklist: if it’s found in the blacklist, Asterisk will transfer the call to the ‘blocked’ extension, to the step with priority 1. The step with priority 1 of the ‘blocked’ extension tells Asterisk to hang up, so Asterisk will end the call; if, on the contrary, the caller’s phone number is not found in the blacklist, Asterisk will just go to the next step of the dial plan, which in this case is to ring (exten => 8611,2,Ringing() or exten => 12020202020,2,Ringing()).

25.20. Call recording

25.20.1. Recording incoming calls

If you want to record the incoming calls to a certain extension (let’s say 601) just add the following two lines before the Dial() line for that extension, in the [context-out] section of /etc/asterisk/extensions.conf:

exten => 601,1,Set(fname=${STRFTIME(${EPOCH},,%Y-%m-%d-%H-%M-%S)}-${CALLERID(number)}-${EXTEN}.wav)
exten => 601,2,MixMonitor(/var/spool/asterisk/recording/${fname})

Then add the following line just before the final Hangup() line for that extension, to stop recording:

exten => 601,n,StopMonitor()

We’ll exemplify with the extension for the Sales Department from the first scenario described above. To implement call recording for all inbound calls to extension 601, make the block dedicated to extension 601 from the [context-out] section in /etc/asterisk/extensions.conf look like this:

; Sales Department
exten => 601,1,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/601)} = UNKNOWN]]?601,2:601,4)
exten => 601,2,VoiceMail(601@voicemail-context,s,u)
exten => 601,3,Hangup()
exten => 601,4,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = INUSE] | [${DEVICE_STATE(PJSIP/601)} = BUSY] | [${DEVICE_STATE(PJSIP/601)} = ONHOLD] | [${DEVICE_STATE(PJSIP/601)} = RINGING]]?601,5:601,8)
exten => 601,5,Answer()
exten => 601,6,Queue(sales-queue,nt,,,1200)
exten => 601,7,Hangup()
exten => 601,8,Set(fname=${STRFTIME(${EPOCH},,%Y-%m-%d-%H-%M-%S)}-${CALLERID(number)}-${EXTEN}.wav)
exten => 601,9,MixMonitor(/var/spool/asterisk/recording/${fname})
exten => 601,10,Dial(PJSIP/601,60)
exten => 601,11,StopMixMonitor()
exten => 601,12,Hangup()

The dial plan lines for call recording in bold from above will make Asterisk record all inbound calls to extension 601; the recording file will have the wav format and will be saved in the /var/spool/asterisk/recording directory. Each recording will have the incoming sound mixed with the outgoing sound, and will bear a name like the following:

2020-05-25-10-08-16-604-601.wav

where the first 6 numbers represent the year, month, day, hour, minute, second of the phone call, while the last two numbers are: the first is the number of the caller, the second is the number of the receiver.

Warn the caller before recording the conversation !

Please note that it is fair-play and even a legal requirement in some states/countries to warn a caller before recording the conversation that they are about to have. To warn all the callers who make calls to extension 601 that their conversation will be recorded, the example from above should be changed to look like this:

; Sales Department
exten => 601,1,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/601)} = UNKNOWN]]?601,2:601,4)
exten => 601,2,VoiceMail(601@voicemail-context,s,u)
exten => 601,3,Hangup()
exten => 601,4,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = INUSE] | [${DEVICE_STATE(PJSIP/601)} = BUSY] | [${DEVICE_STATE(PJSIP/601)} = ONHOLD] | [${DEVICE_STATE(PJSIP/601)} = RINGING]]?601,5:601,8)
exten => 601,5,Answer()
exten => 601,6,Queue(sales-queue,nt,,,1200)
exten => 601,7,Hangup()
exten => 601,8,Playback(warn-about-recording)
exten => 601,9,Wait(1)
exten => 601,10,Set(fname=${STRFTIME(${EPOCH},,%Y-%m-%d-%H-%M-%S)}-${CALLERID(number)}-${EXTEN}.wav)
exten => 601,11,MixMonitor(/var/spool/asterisk/recording/${fname})
exten => 601,12,Dial(PJSIP/601,60)
exten => 601,13,StopMixMonitor()
exten => 601,14,Hangup()

The sound file warn-about-recording.wav, will be recorded as we explained for other sounds (IVR prompts, on-hold messages, voicemail greetings) earlier and copied to the /var/lib/asterisk/sounds/en directory and will contain an audio message, warning the caller that the conversation will be recorded and that if they don’t want to be recorded, they should hang up and contact the company by other means such as email or fax. The warning message can be similar to the following:

“This call will be recorded for record-keeping, training and quality-assurance purposes. If you don’t want to be recorded you can hang up and contact us by email or fax.”

After placing the sound file in the /var/lib/asterisk/sounds/en directory, change ownership and permissions by running:

cd /var/lib/asterisk/sounds/en
chown asterisk:asterisk warn-about-recording.wav
chmod 644 warn-about-recording.wav

25.20.2. Recording outgoing calls

If you want to record all outgoing calls from the Localphone/Telnyx number, you can do it in a similar manner. Change the block dedicated to outgoing calls from the Localphone/Telnyx number, under [context-out], to make it look like this:

[context-out]

; Dial external numbers with Localphone
exten => _9.,1,Playback(this-call-may-be-monitored-or-recorded)
exten => _9.,2,Wait(1)
exten => _9.,3,Set(fname=${STRFTIME(${EPOCH},,%Y-%m-%d-%H-%M-%S)}-${CALLERID(number)}-${EXTEN}.wav)
exten => _9.,4,MixMonitor(/var/spool/asterisk/recording/${fname})
exten => _9.,5,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _9.,6,Answer()
exten => _9.,7,StopMixMonitor()
exten => _9.,8,Hangup()

; Dial external numbers with Telnyx
exten => _8.,1,Playback(this-call-may-be-monitored-or-recorded)
exten => _8.,2,Wait(1)
exten => _8.,3,Set(fname=${STRFTIME(${EPOCH},,%Y-%m-%d-%H-%M-%S)}-${CALLERID(number)}-${EXTEN}.wav)
exten => _8.,4,MixMonitor(/var/spool/asterisk/recording/${fname})
exten => _8.,5,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)
exten => _8.,6,Answer()
exten => _8.,7,StopMixMonitor()
exten => _8.,8,Hangup()

25.21. Conference Calls

To implement conference calls you need to edit two files: /etc/asterisk/confbridge.conf and /etc/asterisk/extensions.conf. Please note that SIP Trip Phone only supports audio conferences, while Roundpin supports both audio and video conferences. The only difference between configuring audio conferences and video conferences is that for video conferences, in the /etc/asterisk/confbridge.conf file, in the [first_bridge] block, the video_mode=sfu line has to be included, as shown below.

First make a copy of the original /etc/asterisk/confbridge.conf file:

cp /etc/asterisk/confbridge.conf /etc/asterisk/confbridge.conf_orig

Then edit /etc/asterisk/confbridge.conf:

nano /etc/asterisk/confbridge.conf

First, add the following lines below the [default_user] line, like this:

[default_user]
type=user
send_events=yes
echo_events=yes

Add the following lines below the [default_bridge] line, like this:

[default_bridge]
type=bridge
video_mode=sfu
enable_events=yes

Then, add the following lines at the bottom of the file:

[first_bridge]
type=bridge
video_mode=sfu
enable_events=yes

[first_bridge_user]
type=user
announce_user_count=yes
send_events=yes
echo_events=yes
talk_detection_events=yes
pin=5115
;announce_join_leave=yes
text_messaging=yes

[first_bridge_menu]
type=menu
1=increase_listening_volume
2=decrease_listening_volume
3=reset_listening_volume
4=increase_talking_volume
5=decrease_talking_volume
6=reset_talking_volume
7=toggle_mute

Replace 5115 with a pin number that only the admin knows and the people invited to the conference. If you want to let participants enter the conference without entering a pin number, just comment out the pin=5115 line.

If you want to record conferences, you can add record_conference=yes in the [first_bridge] block shown above. This will record only the audio stream of audio and video conferences, in the default wav format, and will store it in the /var/spool/asterisk/monitor directory. However, the quality of the recording will be better if you record the conferences using the usual call recording method described in the Record outgoing calls chapter from above. At the moment, only the audio streams of conferences can be recorded. If you want to record both the audio and the video streams of video conferences, the best method is to install OBS Studio on your computer and set it up to record the conference before the conference starts.

If you want the ‘conference assistant’ to announce the name of each participant who joins or leaves the conference, uncomment the ;announce_join_leave=yes line (by removing the semicolon). In that case, each participant will be asked what her/his name is before entering the conference, so that the name will be recorded and repeated to the other participants.

Then edit /etc/asterisk/extensions.conf:

nano /etc/asterisk/extensions.conf

In the [context-out] section, add the following lines:

; Extension that the users can call to enter a conference
exten => 777,1,NoOp()
exten => 777,2,ConfBridge(${EXTEN},first_bridge,first_bridge_user,first_bridge_menu)
exten => 777,3,Hangup()

777 is the extension that the users can call to initiate a new conference or to enter in a conference initiated by others. You can replace 777 with a number of your choice, different from other extensions.

Every user with a phone connected to the Asterisk server will be able to dial 777 to initiate a conference call, or enter the conference initiated by others. If you uncomment the ;announce_join_leave=yes line, before entering the conference every user will be prompted to tell their name and then press the pound key (#). This will record their name, which will be announced to the other participants when the user will enter and when the user will leave the conference. The announce_user_count=yes line ensures that any new participant is informed how many users are already participating in the conference.

Any participant in the conference can increase the listening volume by pressing 1, can decrease the listening volume by pressing 2, can reset the listening volume by pressing 3, can increase the talking volume by pressing 4, can decrease the talking volume by pressing 5, can reset the talking volume by pressing 6 and can mute/unmute themselves by pressing 7.

Restart Asterisk:

systemctl restart asterisk

Please note that the settings from above allow only the users with an endpoint configured in Asterisk to participate in a conference call. What if you want a person from outside your company/organization to be able to participate in an audio conference call together with you and the people in your company/organization ? We’ll show below how you should edit the /etc/asterisk/extensions.conf file in order to achieve this. We’ll modify the settings from the dial plan for the first scenario, but the changes can be adapted to any dial plan.

Open the /etc/asterisk/extensions.conf file:

nano /etc/asterisk/extensions.conf

Add the lines in bold to the dial plan lines for the first scenario:

[context-out]

autohints = yes

; Dial external numbers with Localphone
exten => _9.,1,Dial(PJSIP/${EXTEN:1}@localphone,60,tr)
exten => _9.,2,Answer()
exten => _9.,3,Hangup()

; Dial external numbers with Telnyx
exten => _8.,1,Dial(PJSIP/${EXTEN:1}@telnyx,60,tr)
exten => _8.,2,Answer()
exten => _8.,3,Hangup()

; Extension that the users can call to enter a conference
exten => 777,1,NoOp()
exten => 777,2,ConfBridge(${EXTEN},first_bridge,first_bridge_user,first_bridge_menu)
exten => 777,3,Hangup()

; Sales Department
exten => 601,1,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/601)} = UNKNOWN]]?601,2:601,4)
exten => 601,2,VoiceMail(601@voicemail-context,s,u)
exten => 601,3,Hangup()
exten => 601,4,GotoIf($[[${DEVICE_STATE(PJSIP/601)} = INUSE] | [${DEVICE_STATE(PJSIP/601)} = BUSY] | [${DEVICE_STATE(PJSIP/601)} = ONHOLD] | [${DEVICE_STATE(PJSIP/601)} = RINGING]]?601,5:601,8)
exten => 601,5,Answer()
exten => 601,6,Queue(sales-queue,nt,,,1200)
exten => 601,7,Hangup()
exten => 601,8,Dial(PJSIP/601,60)
exten => 601,9,Hangup()

; Billing Department
exten => 602,1,GotoIf($[[${DEVICE_STATE(PJSIP/602)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/602)} = UNKNOWN]]?602,2:602,4)
exten => 602,2,VoiceMail(602@voicemail-context,s,u)
exten => 602,3,Hangup()
exten => 602,4,GotoIf($[[${DEVICE_STATE(PJSIP/602)} = INUSE] | [${DEVICE_STATE(PJSIP/602)} = BUSY] | [${DEVICE_STATE(PJSIP/602)} = ONHOLD] | [${DEVICE_STATE(PJSIP/602)} = RINGING]]?602,5:602,8)
exten => 602,5,Answer()
exten => 602,6,Queue(billing-queue,nt,,,1200)
exten => 602,7,Hangup()
exten => 602,8,Dial(PJSIP/602,60)
exten => 602,9,Hangup()

; Technical Support Department
exten => 603,1,GotoIf($[[${DEVICE_STATE(PJSIP/603)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/603)} = UNKNOWN]]?603,2:603,4)
exten => 603,2,VoiceMail(603@voicemail-context,s,u)
exten => 603,3,Hangup()
exten => 603,4,GotoIf($[[${DEVICE_STATE(PJSIP/603)} = INUSE] | [${DEVICE_STATE(PJSIP/603)} = BUSY] | [${DEVICE_STATE(PJSIP/603)} = ONHOLD] | [${DEVICE_STATE(PJSIP/603)} = RINGING]]?603,5:603,8)
exten => 603,5,Answer()
exten => 603,6,Queue(techsupport-queue,nt,,,1200)
exten => 603,7,Hangup()
exten => 603,8,Dial(PJSIP/603,60)
exten => 603,9,Hangup()

; Operator
exten => 604,1,GotoIf($[[${DEVICE_STATE(PJSIP/604)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/604)} = UNKNOWN]]?604,2:604,4)
exten => 604,2,VoiceMail(604@voicemail-context,s,u)
exten => 604,3,Hangup()
exten => 604,4,GotoIf($[[${DEVICE_STATE(PJSIP/604)} = INUSE] | [${DEVICE_STATE(PJSIP/604)} = BUSY] | [${DEVICE_STATE(PJSIP/604)} = ONHOLD] | [${DEVICE_STATE(PJSIP/604)} = RINGING]]?604,5:604,8)
exten => 604,5,Answer()
exten => 604,6,Queue(operator-queue,nt,,,1200)
exten => 604,7,Hangup()
exten => 604,8,Dial(PJSIP/604,60)
exten => 604,9,Hangup()

; CEO's extension
exten => 631,1,GotoIf($[[${DEVICE_STATE(PJSIP/631)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/631)} = UNKNOWN]]?631,2:631,4)
exten => 631,2,VoiceMail(631@voicemail-context,s,u)
exten => 631,3,Hangup()
exten => 631,4,GotoIf($[[${DEVICE_STATE(PJSIP/631)} = INUSE] | [${DEVICE_STATE(PJSIP/631)} = BUSY] | [${DEVICE_STATE(PJSIP/631)} = ONHOLD] | [${DEVICE_STATE(PJSIP/631)} = RINGING]]?631,5:631,8)
exten => 631,5,Answer()
exten => 631,6,Queue(ceo-queue,nt,,,1200)
exten => 631,7,Hangup()
exten => 631,8,Dial(PJSIP/631,60)
exten => 631,9,Hangup()

; CTO's extension
exten => 632,1,GotoIf($[[${DEVICE_STATE(PJSIP/632)} = UNAVAILABLE] | [${DEVICE_STATE(PJSIP/632)} = UNKNOWN]]?632,2:632,4)
exten => 632,2,VoiceMail(632@voicemail-context,s,u)
exten => 632,3,Hangup()
exten => 632,4,GotoIf($[[${DEVICE_STATE(PJSIP/632)} = INUSE] | [${DEVICE_STATE(PJSIP/632)} = BUSY] | [${DEVICE_STATE(PJSIP/632)} = ONHOLD] | [${DEVICE_STATE(PJSIP/632)} = RINGING]]?632,5:632,8)
exten => 632,5,Answer()
exten => 632,6,Queue(cto-queue,nt,,,1200)
exten => 632,7,Hangup()
exten => 632,8,Dial(PJSIP/632,60)
exten => 632,9,Hangup()

; Operator
exten => 4,1,Goto(604,1)

; If you dial 5, you can leave a message in the general voicemail box
exten => 5,1,VoiceMail(650@voicemail-context,s,u)
exten => 5,n,Hangup()

; If you dial 7, you can leave a message in the CEO's voicemail box
exten => 7,1,VoiceMail(631@voicemail-context,s,u)
exten => 7,n,Hangup()

; If you dial 8, you can leave a message in the CTO's voicemail box
exten => 8,1,VoiceMail(632@voicemail-context,s,u)
exten => 8,n,Hangup()

; Read voicemail messages
exten => 955,1,Answer(500)
exten => 955,n,VoiceMailMain(@voicemail-context)




[context-in]

autohints = yes

; IVR in case you use Localphone
exten => 8611,1,Ringing()
exten => 8611,2,Wait(0.5)
exten => 8611,3,Answer()
exten => 8611,4,Background(/var/lib/asterisk/sounds/en/ivr-prompts)
exten => 8611,5,Wait(2)
exten => 8611,6,Goto(8611,2)

; IVR in case you use Telnyx
exten => 12020202020,1,Ringing()
exten => 12020202020,2,Wait(0.5)
exten => 12020202020,3,Answer()
exten => 12020202020,4,Background(/var/lib/asterisk/sounds/en/ivr-prompts)
exten => 12020202020,5,Wait(2)
exten => 12020202020,6,Goto(12020202020,2)

; Sales
exten => 1,1,Goto(context-out,601,1)

; Billing
exten => 2,1,Goto(context-out,602,1)

; Technical Support
exten => 3,1,Goto(context-out,603,1)

; Operator
exten => 4,1,Goto(context-out,604,1)

; General voicemail box
exten => 5,1,VoiceMail(650@voicemail-context,s,u)
exten => 5,n,Hangup()

; If you dial 7, you can leave a message in the CEO's voicemail box
exten => 7,1,VoiceMail(631@voicemail-context,s,u)
exten => 7,n,Hangup()

; If you dial 8, you can leave a message in the CTO's voicemail box
exten => 8,1,VoiceMail(632@voicemail-context,s,u)
exten => 8,n,Hangup()

; After the IVR presents all options, if the caller dials 9, (s)he will be sent to the conference number
exten => 9,1,Goto(context-out,777,1)

After listening to the IVR options, the caller can dial 9 to be sent to the conference call, where (s)he can join the conference after entering the pin number (and telling their name). In general, a conference call is not intended to be accessible to every caller from outside the company/organization; thus, since only some callers who will be invited and given the pin number will be accepted to join the conference, there is no point in adding a prompt to the IVR to announce all callers that by pressing 9 they can join the conference. This should remain a ‘secret’ option, intended for the use of the persons who will be invited to the conference. Before the conference, they will be informed (for example by email) about the time when the conference will take place, what key they should press after the IVR prompts, and what pin number they should enter to join the conference.

A simpler method that would allow a caller from outside the company/organization to participate in a conference, would be to have a human operator answer the call and manually transfer the call to the conference extension (here 777). In ‘Roundpin’, a call can be transferred by pressing the ‘Transfer Call’ button which appears during a call. In ‘SIP Trip Phone’ a call can be transferred using the ‘Transfer’ button.

If you want to run two separate conferences simultaneously, you can add the lines for a new extension, 888 for example, below the lines for 777, in /etc/asterisk/extensions.conf. The new extension can use the same bridge, user and menu as 777 (first_bridge,first_bridge_user,first_bridge_menu), or it can use a different bridge, user and menu, with different settings. Then the users who will dial 777 will enter the first conference call, while those dialing 888 will enter the second conference call. You can set up as many conference extensions as you like. Of course, the hardware resources will limit the number of simultaneous conference calls.

25.22. Upgrading Asterisk

To avoid the situation in which an Asterisk upgrade can break some functionalities of Roundpin or SIP Trip Phone, it’s recommended to upgrade Asterisk only together with Debian, once every 2 years. Therefore, even if new versions get released more frequently and they promise to offer numerous improvements, it’s recommended that you give more importance to stability in the context described in this guide, and upgrade Asterisk only once every 2 years, after you upgrade Debian. Before doing the actual Asterisk upgrade, it’s also recommended to check if the new version has been tested and confirmed to function well and as a result it has been included on the list available on this page. If the new Asterisk version that you intend to upgrade to hasn’t been included on the mentioned list, it means it’s safer to compile and install again the old Asterisk version, and upgrade later. (After you upgrade Debian, you need to compile and install Asterisk again, even if you use the old Asterik version that was functioning well on the old Debian version. This is because Asterisk depends on certain Debian packages that can change from one Debian version to the other.)

The only exceptions to the general rule of upgrading Asterisk after upgrading Debian, once every 2 years, should be the cases in which critical security vulnerabilities will be discovered and you will need to install newer versions sooner, to apply the fixes. To find out if and when critical security vulnerabilities will be discovered in Asterisk, you can check web pages like this periodically, or you can subscribe to our ‘Updates Newsletter’. Subscribers get an email each time a security vulnerability that needs to be fixed urgently by an upgrade is discovered in Asterisk, or in any other application that is part of RED SCARF Suite.

When you are ready to upgrade Asterisk, first make a copy of the important folders of the current installation, like this:

cp -r /etc/asterisk /etc/asterisk-old
cp -r /var/lib/asterisk /var/lib/asterisk-old

Then build and install the new version of Asterisk following the exact steps described in the Build and Install Asterisk chapter, up to the line “Next, install the log rotation script by running:”. This means you will need to follow all the instructions, excluding the log rotation configuration and all the other configurations that follow, since you have already implemented them when installing the previous Asterisk version.

Afterwards, make a copy of the most important original configuration files located in the /etc/asterisk directory, like this:

cd /etc/asterisk
cp pjsip.conf pjsip.conf_orig
cp extensions.conf extensions.conf_orig
cp http.conf http.conf_orig
cp rtp.conf rtp.conf_orig
cp modules.conf modules.conf_orig
cp ari.conf ari.conf_orig
cp voicemail.conf voicemail.conf_orig
cp musiconhold.conf musiconhold.conf_orig
cp confbridge.conf confbridge.conf_orig
cp logger.conf  logger.conf_orig

Next, you can look at these original configuration files to see if they seem to have the same default parameteres enabled, as the old ones. If the default parameters that are enabled seem to be the same, you can overwrite the original configuration files with the old ones from /etc/asterisk-old like this:

cp /etc/asterisk-old/pjsip.conf /etc/asterisk
cp /etc/asterisk-old/extensions.conf /etc/asterisk
cp /etc/asterisk-old/http.conf /etc/asterisk
cp /etc/asterisk-old/rtp.conf /etc/asterisk
cp /etc/asterisk-old/modules.conf /etc/asterisk
cp /etc/asterisk-old/ari.conf /etc/asterisk
cp /etc/asterisk-old/voicemail.conf /etc/asterisk
cp /etc/asterisk-old/musiconhold.conf /etc/asterisk
cp /etc/asterisk-old/confbridge.conf /etc/asterisk
cp /etc/asterisk-old/logger.conf /etc/asterisk

If the new configuration files seem to have additional parameters enabled by default, as compared to the configuration files of the old Asterisk version, it’s recommended to leave the original files of the new Asterisk version as they are and just add to them the relevant additional configuration lines from the old files.

Set the right ownership for /etc/asterisk and all the files inside:

chown -R asterisk:asterisk /etc/asterisk

Then you can copy the old IVR prompts, onhold messages, voicemail greetings and voicemail messages for all extensions like this:

cp /var/lib/asterisk-old/sounds/en/ivr-prompts.wav /var/lib/asterisk/sounds/en
cp -r /var/lib/asterisk-old/sounds/en/onhold-general /var/lib/asterisk/sounds/en
cp -r /var/lib/asterisk-old/sounds/en/onhold-ceo /var/lib/asterisk/sounds/en
cp -r /var/lib/asterisk-old/sounds/en/onhold-cto /var/lib/asterisk/sounds/en

Restart Asterisk:

systemctl restart asterisk

You can check the version of the current Asterisk installation by running:

asterisk -V

After you check that the new Asterisk version works as exptected, you can delete the directories of the old installation, to save storage space:

rm -r /etc/asterisk-old
rm -r /var/lib/asterisk-old
You can send your questions and comments to: