Asterisk Real Time

Share on facebook
Share on google
Share on twitter
Share on linkedin
asterisk en tiempo real, asterisk real time, asterisk 17, instalación de asterisk, asterisk rendimiento, asterisk pbx configuracion, asterisk realtime, pbx real time

Asterisk Real Time

1.- Introducción

Después de una larga investigación en internet, googleando por todos lados me di cuenta de que toda la información acerca de Asterisk Real Time era muy vieja entre el año 2005 y 2015 en el mejor de los casos. Aparentemente nadie estaba interesado en transmitir los conocimientos de esta interesante forma de programar Asterisk.

Debido a lo antes expresado me di a la tarea de buscar la información disponible y unirla en una sola guía que haga la vida más sencilla a las personas interesadas en implementar Asterisk Real Time. El mejor conocimiento es el que se comparte con los demás.

2.-Recomendaciones

  1. No recomendamos utilizar el DialPlan en real Time debido a que si tenemos un DialPlan demasiado grande cada vez que hacemos una llamada las consultas a la base da dato podrían sobrecargar el sistema.
  2. En esta guía utilizamos Centos 7, sin embargo, usted puede utilizar Centos 8 o Ubunto si así lo desea.
  3. Tomar en cuenta que Asterisk ya depreco las aplicaciones siguientes:
    • Meetme, desde hace muchas versiones, fue sustituida por confbridge la cual en la actualidad no tiene Real Time.
    • SIP, en la versión 17 de Asterisk SIP fue deprecado, sin embargo, en este manual vamos a cubrir este tipo de dispositivos.
  4.  Nunca realice esta implementación en un servidor en producción.

3.- Instalación

3.1.- Configuración de Firewall

Centos 7 viene generalmente con el firewall activado y los puertos 5060-5063 y 10000-20000 bloqueados, por tal razón podríamos tener problemas al momento de querer registrar las extensiones SIP o PJSIP. A continuación, aplicaremos las reglas de firewall para evitar este problema.

[root@localhost ~]# systemctl start firewalld
[root@localhost ~]# systemctl enable firewalld
[root@localhost ~]# firewall-cmd --zone=public --add-port=5060-5063/udp --permanent
[root@localhost ~]# firewall-cmd --zone=public --add-port=5060-5063/tcp --permanent
[root@localhost ~]# firewall-cmd --zone=public --add-port=10000-20000/udp --permanent

3.2.- Instalación de Asterisk 17

En esta guía vamos a suponer que usted ya instalo Centos 7 minimal, por lo cual vamos a comenzar instalado Asterisk 17 y sus dependencias. Para ingresar a la consola de Centos 7 puede utilizar un ssh cliente como por ejemplo Putty.

Instalar Linux Centos 7.8 y hacerle update

[root@localhost ~]# yum update -y

Desabilitar SELinux en Centos 7

[root@localhost ~]# vi /etc/selinux/config
Cambiar la línea:SELINUX=enforcingPor el valor deSELINUX=disabled
[root@localhost ~]# reboot

Instalar dependencias

[root@localhost ~]# yum install -y epel-release dmidecode gcc-c++ ncurses-devel libxml2-devel make wget openssl-devel newt-devel kernel-devel sqlite-devel libuuid-devel gtk2-devel jansson-devel binutils-devel libedit libedit-devel

Agregar usuario asterisk

[root@localhost ~]# adduser asterisk -c "Asterisk User"
[root@localhost ~]# passwd asterisk
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
[root@localhost ~]# usermod -aG wheel asterisk

Ahora vamos a instalar Asterisk 17

[root@localhost ~]# cd /usr/src
[root@localhost src]# wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-17-current.tar.gz
[root@localhost src]# tar -zxvf asterisk-17-current.tar.gz
[root@localhost src]# cd asterisk-17.4.0
[root@localhost asterisk-17.4.0]# yum install svn -y
[root@localhost asterisk-17.4.0]# ./contrib/scripts/get_mp3_source.sh
[root@localhost asterisk-17.4.0]# contrib/scripts/install_prereq install
[root@localhost asterisk-17.4.0]# ./configure --libdir=/usr/lib64 --with-jansson-bundled --with-pjproject-bundled
Ahora procederemos con
[root@localhost asterisk-17.4.0]# make menuselect

Nos aseguramos de que en Channel Drivers este seleccionado chan_sip, también podemos seleccionar opciones como diferentes audios y códecs como por ejemplo opus. Después de haber seleccionado todo lo que necesitamos procedemos a Save & Exit.

Ahora procederemos con los
[root@localhost asterisk-17.4.0]# make && make install
[root@localhost asterisk-17.4.0]# make samples
[root@localhost asterisk-17.4.0]# make config
[root@localhost asterisk-17.4.0]# chown asterisk. /var/run/asterisk
[root@localhost asterisk-17.4.0]# chown asterisk. -R /etc/asterisk
[root@localhost asterisk-17.4.0]# chown asterisk. -R /var/{lib,log,spool}/asterisk
[root@localhost asterisk-17.4.0]# chkconfig asterisk on
[root@localhost asterisk-17.4.0]# systemctl start asterisk
[root@localhost asterisk-17.4.0]# asterisk -rvvvvvvvvvvvvvvvvvvv
Asterisk 17.4.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 17.4.0 currently running on localhost (pid = 91658)
localhost*CLI>

Felicidades, usted ha instalado Asterisk 17 perfectamente!

3.3.- Instalación de Mariadb y dependencias.

Para que Asterisk Real Time funcione es necesario instalar mariadb, ya que la aplicación de realtime funciona con bases de datos y se conecta por odbc.

[root@localhost ~]# yum install -y mysql-connector-odbc mariadb mariadb-server
[root@localhost ~]# systemctl enable mariadb
[root@localhost ~]# systemctl start mariadb

Desde la versión 12 la creación de las tablas para Asterisk Realtime se realiza utilizando alembic. Con la misma aplicación es posible migrar a la última versión de Asterisk y actualizar las tablas creadas con la versión 11 o anteriores. Primero se instalan unas dependencias:

[root@localhost ~]# yum install MySQL-python python-pip -y

Luego se instala elembi via PIP:

[root@localhost ~]# pip install alembic

Como la creación/actualización de las tabla se basa en un archivo de configuración, lo modificamos:

[root@localhost ~]# cd /usr/src/asterisk-17.4.0/contrib/ast-db-manage/
[root@localhost ast-db-manage]# mv config.ini.sample config.ini
[root@localhost ast-db-manage]# vi config.ini
Cambiamos esta línea: sqlalchemy.url = mysql://user:pass@localhost/asterisk para que quede: sqlalchemy.url = mysql://root:@localhost/asterisk

La sintaxis de la línea es: motor de base de datos, usuario, contraseña, dominio/IP, base de datos. Con esta línea se crea la conexión a la base de datos. Guardamos los cambios y pasamos a la creación de la base de datos:

[root@localhost ~]# mysql -u root 
MariaDB [(none)]> create database asterisk;
MariaDB [(none)]> exit;

creamos/actualizamos las tablas con el siguiente comando:

[root@localhost ~]# cd /usr/src/asterisk-17.4.0/contrib/ast-db-manage/
[root@localhost ast-db-manage]# alembic -c config.ini upgrade head

Volvemos a ingresar en MariaDB:

[root@localhost ~]# mysql -u root 
MariaDB [(none)]> use asterisk;
MariaDB [(asterisk)]> show tables;
+-----------------------------+
| Tables_in_asterisk          |
+-----------------------------+
| alembic_version_config      |
| extensions                  |
| iaxfriends                  |
| meetme                      |
| musiconhold                 |
| musiconhold_entry           |
| ps_aors                     |
| ps_asterisk_publications    |
| ps_auths                    |
| ps_contacts                 |
| ps_domain_aliases           |
| ps_endpoint_id_ips          |
| ps_endpoints                |
| ps_globals                  |
| ps_inbound_publications     |
| ps_outbound_publishes       |
| ps_registrations            |
| ps_resource_list            |
| ps_subscription_persistence |
| ps_systems                  |
| ps_transports               |
| queue_members               |
| queue_rules                 |
| queues                      |
| sippeers                    |
| voicemail                   |
+-----------------------------+
26 rows in set (0.00 sec)

Ahora creamos un usuario que tenga los privilegios suficientes para trabajar con la base de datos creada:

MariaDB [asterisk]> grant all privileges on asterisk.* to 'asterisk'@'localhost' identified by 'asterisk';
Query OK, 0 rows affected (0.00 sec)
MariaDB [asterisk]> FLUSH Privileges;
MariaDB [asterisk]> exit;

Por alguna razón que desconocemos en la tabla sippeers se crea primero el campo permit y después el deny, esto ocasiona que el crear una extensión con dispositivo sip nos dé un error de ACL al querer registrarse la extensión, para evitar este problema recomendamos eliminar los dos campos y crearlos de nuevo, pero en el orden de primero deny y después permit, para esto hacemos lo siguiente:

MariaDB [asterisk]> ALTER TABLE sippeers DROP COLUMN deny;
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0

MariaDB [asterisk]> ALTER TABLE sippeers DROP COLUMN permit;
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0

MariaDB [asterisk]> ALTER TABLE sippeers ADD(deny varchar(95) Default '0.0.0.0/0');
Query OK, 1 row affected (0.04 sec)
Records: 1  Duplicates: 0  Warnings: 0

MariaDB [asterisk]> ALTER TABLE sippeers ADD(permit varchar(95) Default '0.0.0.0/0');
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0
MariaDB [asterisk]> exit;

3.4.- Configuración de Asterisk

Pasamos a la configuración de ODBC y Asterisk para que el Realtime funcione correctamente. El archivo odbcinst.ini, presente en la carpeta etc, lo dejamos con la configuración predefinida. Creamos el archivo odbc.ini donde configuraremos la conexión a la base de datos asterisk:

[root@localhost ~]# vi /etc/odbc.ini
[asterisk]
Description = MySQL Asterisk
Driver = MySQL
Database = asterisk
Server = localhost
User = asterisk
Password = asterisk
Port = 3306
Option = 3

Guardamos los cambios y verificamos que la conexión esté funcionando correctamente:

[root@localhost ~]# isql asterisk asterisk asterisk
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> quit;

Perfecto. Ahora pasamos a la configuración de Asterisk y agregamos al final lo siguiente:

[root@localhost ~]# vi /etc/asterisk/res_odbc.conf
[asterisk]
enabled => yes
dsn => asterisk
username => asterisk
password => asterisk
pre-connect => yes
sanitysql => select 1
max_connections => 20
connect_timeout => 5
negative_connection_cache => 600

Ahora configuramos el archivo de Asterisk extconfig.conf

[root@localhost ~]# vi /etc/asterisk/extconfig.conf
;
; Static and realtime external configuration
; engine configuration
;
; See https://wiki.asterisk.org/wiki/display/AST/Realtime+Database+Configuration
; for basic table formatting information.
;
[settings]
ps_endpoints => odbc,asterisk
ps_auths => odbc,asterisk
ps_aors => odbc,asterisk
ps_domain_aliases => odbc,asterisk
ps_endpoint_id_ips => odbc,asterisk
ps_contacts => odbc,asterisk
voicemail => odbc,asterisk
queues => odbc,asterisk
queue_members => odbc,asterisk
sipusers => odbc,asterisk
sippeers => odbc,asterisk
extensions => odbc,asterisk

Como podemos ver estamos configurando para RealTime los dispositivos PJSIP (todo lo que empieza con ps), voicemail, dispositivos SIP, queues, queues members y extensions

Ahora configuramos el archivo de Asterisk pjsip.conf. Agregamos al final las siguientes líneas.

[root@localhost ~]# vi /etc/asterisk/pjsip.conf
[system]
type=system
timer_t1=500
timer_b=32000
disable_tcp_switch=yes

[transport-tcp]
type=transport
protocol=tcp
bind=0.0.0.0:5062
allow_reload=yes

[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0:5062
allow_reload=yes

[transport-tls]
type=transport
protocol=tls
bind=0.0.0.0:5063
allow_reload=yes
verify_client=no
verify_server=no
method=tlsv1

[transport-ws]
type=transport
protocol=ws
bind=0.0.0.0:5062
allow_reload=yes

[transport-wss]
type=transport
protocol=wss
bind=0.0.0.0:5063
allow_reload=yes

Ahora agregamos al final del archivo sorcery.conf en /ect/asterisk/ y le incluimos la siguiente configuración.

[root@localhost ~]# vi /etc/asterisk/sorcery.conf
[res_pjsip]
endpoint=realtime,ps_endpoints
auth=realtime,ps_auths
aor=realtime,ps_aors
domain_alias=realtime,ps_domain_aliases

[res_pjsip_endpoint_identifier_ip]
identify=realtime,ps_endpoint_id_ips

Antes de reiniciar Asterisk para que tome en cuenta los cambios es necesario asegurarnos de que los módulos relacionados con realtime se carguen correctamente en Asterisk.

Así que agregamos los siguientes módulos: preload => res_odbc.so preload => res_config_odbc.so load => func_realtime.so load => pbx_realtime.so
[root@localhost ~]# vi /etc/asterisk/modules.conf
;
; Asterisk configuration file
;
; Module Loader configuration file
;
[modules]
autoload=yes
preload => res_odbc.so
preload => res_config_odbc.so
load => func_realtime.so
load => pbx_realtime.so

Si deseamos trabajar con dispositivos tipo SIP es necesario comentar la siguiente línea: noload => chan_sip.so

[root@localhost ~]# vi /etc/asterisk/modules.conf
; Do not load chan_sip by default, it may conflict with res_pjsip.
;noload => chan_sip.so

Ahora reiniciamos nuestro Asterisk y comprobamos que la conexión funciona.

root@localhost ~]# systemctl restart asterisk
[root@localhost ~]# asterisk -rvvvvvvvvvvvv
localhost*CLI> odbc show

ODBC DSN Settings
-----------------

  Name:   asterisk
  DSN:    asterisk
    Number of active connections: 1 (out of 20)
    Logging: Disabled

localhost*CLI>

3.5.- Agregando Dispositivos PJSIP y SIP

Ahora vamos a agregar algunas extensiones SIP y PJSIP para lo cual debemos agregar registros con los datos en nuestra base de datos de Asterisk creada anteriormente.

Agregando extensión con dispositivo PJSIP.
[root@localhost ~]# mysql -u root
MariaDB [(none)]> use asterisk;
MariaDB [(asterisk)]> insert into ps_aors (id, max_contacts, qualify_frequency) values (100, 2, 30);
MariaDB [(asterisk)]> insert into ps_auths (id, auth_type, password, username) values (100, 'userpass', 100, 100);100, 100);
MariaDB [(asterisk)]> insert into ps_endpoints (id, transport, aors, auth, context, disallow, allow, direct_media, deny, permit, mailboxes) values (100, 'transport-udp', '100', '100', 'testing', 'all', 'all', 'no', '0.0.0.0/0', '0.0.0.0/0', '100@default');
MariaDB [(asterisk)]> exit;

Repetimos estas líneas con diferentes números de extensión para crear nuevas extensiones.

Para verificar que todo este funcionado bien realizamos la siguiente prueba:

[root@localhost ~]# asterisk -rvvvvvvvvvvvvvvvvvv
localhost*CLI> pjsip show endpoints

Endpoint:  <Endpoint/CID.....................................>    
    I/OAuth:  <AuthId/UserName...........................................................>
        Aor:    
      Contact:  <Aor/ContactUri..........................>   <RTT(ms)..>
  Transport:          
   Identify:  <Identify/Endpoint.........................................................>
        Match:  
    Channel:      
        Exten:   CLCID: 
==========================================================================================

Endpoint:  100                                                  Unavailable   0 of inf
     InAuth:  100/100
        Aor:  100                                                2
  Transport:  transport-udp             udp      0      0  0.0.0.0:5062

Objects found: 1

A continuación, vamos a agregar una extensión con dispositivo tipo SIP.

[root@localhost ~]# mysql -u root
MariaDB [(none)]> use asterisk;
MariaDB [(asterisk)]> insert into sippeers (name, host, type, context, deny, permit, secret, transport, disallow, allow, directmedia, language, mailbox) values (101, 'dynamic', 'friend', 'testing', '0.0.0.0/0', '0.0.0.0/0', 101, 'udp', 'all', 'all', 'nonat', 'en', '101@default');
MariaDB [(astrisk)]> exit;

Repetimos estas líneas con diferentes números de extensión para crear nuevas extensiones.

Para verificar que todo este funcionado bien realizamos la siguiente prueba:

[root@localhost ~]# asterisk -rvvvvvvvvvvvvvvvvvv
localhost*CLI> sip show peers
Name/username             Host                                    Dyn Forcerport Comedia    ACL Port     Status      Description                      Realtime
0 sip peers [Monitored: 0 online, 0 offline Unmonitored: 0 online, 0 offline]
localhost*CLI>

Seguramente no aparecerá ningún dispositivo ya que en el caso de SIP estos se muestran en el momento del registro de este. Para que se muestren es necesario agregar en la sección [general]: rtcachefriends=yes

[root@localhost ~]# vi /etc/asterisk/sip.conf
[general]
rtcachefriends=yes

3.6.- Agregando Dial Plan

A como mencionamos al inicio de este manual no es recomendado utilizar el dial plan de forma dinámica, además hemos realizado pruebas y al parecer no  funciona adecuadamente y Asterisk se reinicia.

Ahora que ya tenemos dos extensiones agregadas, deseamos poder hacer llamadas entre ellas, para eso necesitamos crear un dial plan en forma estática el cual configuramos en el archivo extensions.conf del directorio /etc/asterisk.

[root@localhost ~]# vi /etc/asterisk/extensions.conf
[general]

[testing]
exten => 100,1,NoOp(Call Extension ${EXTEN})
 same => n,Dial(PJSIP/${EXTEN},20)
 same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)
 same => n(unavail),Voicemail(100@default,u)
 same => n,Hangup()
 same => n(busy),VoiceMail(100@default,b)
 same => n,Hangup()

exten => 101,1,NoOp(Call Extension ${EXTEN})
 same => n,Dial(SIP/${EXTEN},20)
 same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)
 same => n(unavail),Voicemail(101@default,u)
 same => n,Hangup()
 same => n(busy),VoiceMail(101@default,b)
 same => n,Hangup()

;Retrieve Voicemail message
exten => *97,1,NoOp(Retrieve VM from Extension ${CALLERID(number)})
 same => n,Answer()
 same => n,VoiceMailMain(${CALLERID(num)}@default)

Reiniciamos el Dial Plan

[root@localhost ~]# asterisk -rvvvvvvvvvvvvvvvvvvvv
localhost*CLI> dialplan reload

Felicidades, ya pudimos hacer una llamada entre dos extensiones en Asterisk Real Time.

3.7.- Agregamos Correo de Voz

Es posible que las extensiones tengan su propio correo de voz en real time, para poder tener esta opción es necesario seguir los siguientes pasos:

[root@localhost ~]# mysql -u root
MariaDB [(none)]> use asterisk;
MariaDB [(asterisk)]> insert into voicemail (context, mailbox, password, attach, saycid, envelope) values ('default', '100', '100', 'yes', 'yes', 'yes');
MariaDB [(asterisk)]> insert into voicemail (context, mailbox, password, attach, saycid, envelope) values ('default', '101', '101', 'yes', 'yes', 'yes');
MariaDB [(none)]> exit:

3.8.- Agregando Colas de Llamadas

A continuación, vamos a implementar Queues en Real Time, tienen dos componentes, el primero son los parámetros de la cola y el segundo son los agentes dinámicos y estáticos.

Vamos a agregar los parámetros de la cola en la tabla queues y un miembro estático. Para agregar miembros dinámicos lo haremos mediante el Dial Plan.

[root@localhost ~]# mysql -u root
MariaDB [(none)]> use asterisk;
MariaDB [(asterisk)]> insert into queues (name, musiconhold, timeout, ringinuse, queue_holdtime, retry, wrapuptime, strategy) values ('Q500', 'default', '15', 'no', '30', '5', '5', 'ringall');
MariaDB [(asterisk)]> insert into queue_members (queue_name, interface, membername, penalty, wrapuptime) values ('Q500', 'Local/101@testing/n', '101', '0', '5');
MariaDB [(none)]> exit;

Verificamos que está funcionando.

[root@localhost ~]# asterisk -rvvvvvvvvvvvvvvvvvvvvvvv
localhost*CLI> queue show Q500
Q500 has 0 calls (max unlimited) in 'ringall' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0%, SL2:0.0% within 0s
   Members:
      101 (Local/101@testing/n) (ringinuse disabled) (realtime) (Not in use) has taken no calls yet
   No Callers

localhost*CLI>exit

Ahora vamos a modificar el Dial Pan para poder llamar a la cola. Agregamos al final del Dial Plan ya hecho en el punto 3.6 lo siguiente

[root@localhost ~]# vi /etc/asterisk/extensions.conf

;Call Queue Q500
exten => 500,1,NoOp(Queue: Testing 500)
 same => n,Playback(queue-youarenext)
 same => n(qconnect),NoOp(Connecting to Queue)
 same => n,Queue(Q500,c,,,30)
 same => n,Hangup()
;Agent Login & Logout
exten => *5001,1,NoOp(Queue: Add Agent ${CALLERID(number)} in Queue 500)
 same => n,AddQueueMember(Q500,Local/${CALLERID(number)}@testing/n,0,,${CALLERID(number)},)
 same => n,Playback(agent-loginok)
exten => *5002,1,NoOp(Queue: Remove Agent ${CALLERID(number} in Queue 500)
 same => n,RemoveQueueMember(Q500,Local/${CALLERID(number)}@testing/n)
 same => n,Playback(agent-loggedoff)

Reiniciamos el Dial Plan

[root@localhost ~]# asterisk -rvvvvvvvvvvvvvvvvvvvv
localhost*CLI> dialplan reload

Ahora llamamos de la extensión 100 a la extensión 500 y debería de darnos un mensaje que su llamada es ahora la primera en línea y después repicar en la extensión 101.

Después llamamos de la extensión 101 a la 500 y veremos que nos dejara en espera durante 30 segundos y se cortara la llamada, esto sucede porque no hay agentes disponibles para atender y el tiempo máximo de espera lo programamos en 30 segundos. El teléfono del que estamos llamando la extensión 100 si tiene doble línea posiblemente va a repicar, ignoramos este repique para esta prueba.

Ahora vamos a agregar de forma dinámica a la extensión 100 marcando *5001 de la misma. Y a continuación llamamos a la cola de la extensión 101 y veremos que repicara la extensión 100.

Para remover la extensión 100 de la cola solo debe marcar *5002.

Felicidades, ha implementado la aplicación Queue en Real Time!

Esperamos que disfrutara la implementación de Asterisk Real Time, si desea más información no olvide de visitar nuestra página web vitalpbx.org.

Rodrigo Cuadra

Rodrigo Cuadra

Leave a Reply

About Us

This project started with the objective of creating a system/interface for the administration of PBX systems based on Asterisk,  easy to use, totally adapted for different mobile devices (Fully Responsive Design), and with all the characteristics of an advanced telecommunications system; Combining the flexibility from Asterisk with concepts that have been satisfactorily used in traditional telephone systems, concepts that somehow were ignored by the new generations of IP telephony.

Recent Posts

Follow Us

VitalPBX Overview