Virtual PBX. Part 3: We translate Asterisk to PjSIP without unnecessary gestures





In the first and second parts of a series of articles, we figured out how to install an IP-PBX (IP-PBX) on a VPS from RuVDS running Ubuntu and configure basic functions using the chan_sip channel driver. This approach is deprecated and chan_sip support will be dropped in future versions of Asterisk. It is better to use the open source PjSIP multimedia library instead. Despite the dramatic differences in the configuration files, the transition is not as difficult as it might seem at first glance.



What is PjSIP?



It is important to understand that PjSIP is not some new protocol, but a whole library for working with a stack of protocols that provide voice communication: SIP, RTP, SDP, STUN, etc. It is a whole bunch of modules, which is reflected in the pjsip.conf configuration file (it replaces the traditional sip.conf). The file is divided into sections, and the res_pjsip module works with it mainly, with each section defining the configuration of some object. Section names are traditionally enclosed in square brackets, and a section must contain the "type =" construction that defines its type.



The types of sections can be as follows:



ENDPOINT - analog of the peer in sip.conf, which defines the options for the SIP protocol and interactions with AOR, AUTH and TRANSPORT. Necessarily linked to at least one AOR section;

AOR- describes how to contact ENDPOINT;

TRANSPORT - This section describes transport layer protocol settings, websockets, and encryption methods (like the general in sip.conf). Can be one for different ENDPOINTs or unique for a point;

REGISTRATION - responsible for outgoing registrations, for example, trunks to providers;

AUTH - Contains options and authorities for inbound and outbound registrations. Associated with it are ENDPOINT and REGISTRATIONS;

IDENTIFY - here you can set the source IP for ENDPOINT;

ACL - used by res_pjsip to control incoming connections, not tied to ENDPOINT;

DOMAIN_ALIAS - domain aliases;

CONTACT- needed to not explicitly specify the SIP URI in Dialplan;

System - system options;

Global - global options;



Section names can be arbitrary in most cases, but, for example, ENDPOINT and AOR must be named identically to the SIP URI header.



Our help can hardly be called exhaustive, since there are many interesting chips left behind the scenes, like the PjSIP Configuration Wizard: while we are talking about migration to a new library with little blood. You can deal with the nuances and subtleties later.



Convert sip.conf to pjsip.conf



Because of the modularity, the structure of the pjsip.conf configuration file is spread out in a thin layer over many sections - it is much more complex than the good old sip.conf. Asterisk developers thought of simple admins and created a script to convert. It is written in Python, and if you build software from source, it is already in the distribution: in the contrib / scripts / sip_to_pjsip / directory . We installed Asterisk from a binary package included in the Ubuntu repository, so the scripts had to be downloaded from GitHub.



Although the format of configuration files for different versions of IP-PBX has not changed much, it is better to choose scripts from the version of Asterisk you have installed instead of the latest default - in our case 16.2.





The Asterisk version can be viewed in the IP-PBX console using the core show version command.



You will need all the Python files from the ontrib / scripts / sip_to_pjsip / directory in the repository on GitHub. They need to be added to a local directory, go to the directory with Asterisk configs (usually / etc / asterisk) and run the sip_to_pjsip.py scriptwith superuser privileges. Its main task is to read the input sip.conf file and make a new pjsip.conf (see the Asterisk wiki for details).





The script will make pjsip.conf, and then you will have to manually polish it. If you installed Asterisk according to our articles, you will also have to configure the loading of modules in /etc/asterisk/modules.conf and change the call to the Dial application in Dialplan ( /etc/asterisk/extensions.conf ).



The file /etc/asterisk/pjsip.conf made by the converter turned out to be inoperative in practice:



pjsip.conf
;--
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Non mapped elements start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[general]
allowoverlap = no

[office]
call-limit = 2

[sipnet]
remotesecret = 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Non mapped elements end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
--;


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

[sipnet]
type = aor
contact = sip:@sipnet.ru

[sipnet]
type = identify
endpoint = sipnet
match = sipnet.ru

[sipnet]
type = endpoint
context = sipnet-trunk
dtmf_mode = rfc4733
disallow = all
allow = alaw,ulaw
direct_media = no
from_user = 
from_domain = sipnet.ru
aors = sipnet

[1001]
type = aor
max_contacts = 1

[1001]
type = auth
username = 1001
password = 

[1001]
type = endpoint
context = homeoffice
dtmf_mode = rfc4733
disallow = all
allow = ulaw
allow = alaw
allow = g729
allow = g723
allow = g726
allow = h261
allow = h263
allow = h264
allow = h263p
callerid =  <1001>
auth = 1001
outbound_auth = 1001
aors = 1001

[acl]
type = acl
permit = XXX.XXX.XXX.XXX
deny = 0.0.0.0/0.0.0.0

[1002]
type = aor
max_contacts = 1

[1002]
type = auth
username = 1002
password = 

[1002]
type = endpoint
context = homeoffice
dtmf_mode = rfc4733
disallow = all
allow = ulaw
allow = alaw
allow = g729
allow = g723
allow = g726
allow = h261
allow = h263
allow = h264
allow = h263p
callerid =  <1002>
auth = 1002
outbound_auth = 1002
aors = 1002




Its syntax is straightforward, details can be found in the Asterisk wiki . It will take manual editing to get the config file clean.



Corrected /etc/asterisk/pjsip.conf (as in sip.conf, templates can be used in it):



Corrected /etc/asterisk/pjsip.conf
;===============TRANSPORT

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

;===============ACL

[acl]
type = acl
deny = 0.0.0.0/0.0.0.0
permit = XXX.XXX.XXX.XXX

;===============SIPNET TRUNK

[sipnet]
type = registration
transport = transport-udp
outbound_auth = sipnet
server_uri = sip:sipnet.ru
client_uri = sip:@sipnet.ru
retry_interval = 60

[sipnet]
type = auth
auth_type = userpass
password = 
username = 

[sipnet]
type = aor
contact = sip:@sipnet.ru

[sipnet]
type = endpoint
transport = transport-udp
;      Dialplan
context = sipnet-trunk
dtmf_mode = rfc4733
disallow = all
allow = alaw,ulaw
direct_media = no
from_user = 
from_domain = sipnet.ru
outbound_auth=sipnet
aors = sipnet
 
[sipnet]
type = identify
endpoint = sipnet
match = sipnet.ru

;===============USER TEMPLATES
 
[endpoint-template](!)
type = endpoint
transport = transport-udp
context = homeoffice
dtmf_mode = rfc4733
disallow = all
allow = ulaw
allow = alaw
allow = g729
allow = g723
allow = g726
allow = h261
allow = h263
allow = h264
allow = h263p
 
[auth-template-userpass](!)
type = auth
auth_type = userpass
 
[aor-template-single-reg](!)
type = aor
; PjSIP       
max_contacts = 1

;===============User 1001

[1001](endpoint-template)
auth = auth1001
aors = 1001
callerid =  <1001>

[auth1001](auth-template-userpass)
username = 1001
password = 
 
[1001](aor-template-single-reg)

;===============User 1002

[1002](endpoint-template)
auth = auth1002
aors= 1002
callerid =  <1002>

[auth1002](auth-template-userpass)
username = 1002
password = 
 
[1002](aor-template-single-reg)




With templates, there is less paperwork, but there is also a more interesting way to simplify the admin's life - the Configuration Wizard. Perhaps this is one of the most convenient PjSIP tricks, which we will deal with in the next article.



Rewriting Dialplan



The simplest part: it is enough to replace SIP with PJSIP in the call to the Dial application. While we have slightly modified the simplest test Dialplan from the previous article , we will deal with more complex things later.



Config file /etc/asterisk/extensions.conf
[general]
static=yes
writeprotect=no
priorityjumping=no
autofallthrough=yes
clearglobalvars=no

;         
[default]
exten => _X.,1,NoOp()
same => n,Busy()
same => n,HangUp()

;   homeoffice
[homeoffice]
;   
exten => _1XXX,1,Dial(PJSIP/${EXTEN})
;      SIPNET
exten => _.7XXXXXXXXXX,1,Dial(PJSIP/${EXTEN:1}@sipnet)

;   sipnet-trunk,     SIPNET
[sipnet-trunk]
;      


The transition from chan_sip to PjSIP turned out to be not particularly difficult, but it requires a fair amount of manual work. We failed to convert the configuration automatically: the script produced an inoperable version, which had to be rewritten manually. In the next article, we will take a look at the Configuration Wizard and finally extend dialplan to receive incoming calls, organize conferences and solve other call routing tasks.










All Articles