How we translated MIKOPBX from chan_sip to PJSIP

Background

The material was originally prepared as a report for asterconf 2020 . Now I will try to describe everything in more detail in this article.

MIKOPBX is a free open source PBX based on Asterisk 16 . A year ago, we took up the transition to PJSIP.

Main reasons:

  • PJSIP supports " multiple registration ". You can easily register multiple end UACs on one account

  • Correct operation of incoming routing when setting up registration of multiple provider accounts on one address ( IP + PORT )

  • PJSIP is more flexible in configuration

  • chan_sip is not evolving and is deprecated in Asterisk 17

Next, I will describe what difficulties we encountered and what benefits we received.


The main reason is the need to support " multiple registration ". It is extremely convenient to connect several softphones / phones to your account and do not worry, an incoming call will arrive wherever you are.

Personally, I have the following devices connected:

  • Hardware phone on desktop in office

  • Softphone on laptop

  • Softphone on smartphone

When an incoming call arrives at the extension, all devices ring simultaneously.

?

sip.conf. , ( pjsip.conf ).

asterisk. :

contrib/scripts/sip_to_pjsip/sip_to_pjsip.py

:

Usage: sip_to_pjsip.py [options] [input-file [output-file]]
Converts the chan_sip configuration input-file to the chan_pjsip output-file.
The input-file defaults to 'sip.conf'.
The output-file defaults to 'pjsip.conf'.

.

, ( endpoint).

Asterisk contact.

"max_contacts" , endpoint.

;pjsip.conf
[226] 
type = aor
max_contacts = 5

CLI Asterisk:

mikopbx*CLI> pjsip show contacts

  Contact:  <Aor/ContactUri..............................> <Hash....> <Status> <RTT(ms)..>
==========================================================================================

  Contact:  201/sip:201@172.16.156.1:60616;ob              418d36496b Avail         3.793
  Contact:  201/sip:201@172.16.156.1:60616;ob              ba56853d54 Avail         2.189
  Contact:  203/sip:203@172.16.156.1:60616;ob              2cd641799f Avail         0.988

Objects found: 3

, , dialplan.

c :

;extensions.conf
[internal-users]

;    3   
; PJSIP_DIAL_CONTACTS -   Dial-   
;    &
;       ID endpoint
exten => _XXX,1,Set(dialContacts=${PJSIP_DIAL_CONTACTS(${EXTEN})}) 

;  Dial    
;    "dialContacts"
;  ,   endpoint   
same => n,ExecIf($["${dialContacts}x" != "x"]?Dial(${DC},,Tt))

dialplan .

. , , asterisk " " " ". , .

SIP PJSIP SIP "PBX - UAC".

INVITE = SIP/104-0000XX.

endpoint , INVITE , .

, :

  • , AMI

  • dialplan

  • CDR

, , , :

  • CTI , AMI

. Paging. Intercom

. "". , .

UAC . " " INVITE . :

Call-Info:\;answer-after=0

, .

chan_sip originate SIPADDHEADER:

Action: Originate
Channel: SIP/104
Context: from-internal
Exten: 74952293042
Priority: 1
Callerid: 104
Variable: SIPADDHEADER="Call-Info:\;answer-after=0"

chan_sip.  INVITE.

PJSIP . extensions.conf:

[internal-users] 
exten => 204,1,Dial(${PJSIP_DIAL_CONTACTS(204)},,Ttb(dial_create_chan,s,1)))

[dial_create_chan] 
exten => s,1,Set(PJSIP_HEADER(add,Call-Info)=\;answer-after=0) 
same => n,return 

"b" "Dial" Gosub "dial_create_chan".

SIP INVITE.

: "dial_create_chan" - dialplan, , SIP .

:

[internal-users] 
;  :
exten => _XXX,1,Set(d=${PJSIP_DIAL_CONTACTS(${EXTEN})})
  ;   :
  same => n,ExecIf($["${FIELDQTY(d,&)}"!="1"]?Set(__SIPADDHEADER=${EMPTY})) 
  same => n,ExecIf($["${d}x" != "x"]?Dial(${DC},,Ttb(dial_create_chan,s,1)))

[dial_create_chan] 
exten => s,1,ExecIf($["${SIPADDHEADER}x" == "x"]?return)
  same => n,Set(header=${CUT(SIPADDHEADER,:,1)})
  same => n,Set(value=${CUT(SIPADDHEADER,:,2)})
  same => n,Set(PJSIP_HEADER(add,${header})=${value})
  same => n,Set(__SIPADDHEADER=${EMPTY}) 
  same => n,return 

"FIELDQTY" , endpoint. , , , .

"CUT" "SIPADDHEADER", .

, PJSIP_HEADER SIPADDHEADER. "" .

UserAgent

SIP endpoint. pjsip . :

[get-user-agent]
exten => 300,1,NoOp(--- Incoming call ---)
  same => n,Set(vContact=${PJSIP_AOR(300,contact)})
  same => n,Set(vUserAgent=${PJSIP_CONTACT(${vContact},user_agent)})
  same => n,NoOp(--- ${vContact} & ${vUserAgent} ---)
  ... ... ... 
  same => n,Hangup()

AOR ID 300. ID endpoint = ID AOR = EXTEN:

; ${PJSIP_CONTACT(${PJSIP_AOR(${EXTEN},contact)},user_agent)}

"PJSIP_AOR" ID AOR, , "contact".

"PJSIP_CONTACT" , , "user_agent".

, PJSIP_AOR(300,contact) ID , , CLI.

PJSIP_AOR:

201;@e758f5661420b391e239386a94edbefe

CLI:

pjsip show contacts 201/sip:201@172.16.156.1:57130;ob
Contact:  201/sip:201@172.16.156.1:57130;ob

Asterisk, :

(temporary)

  • No Response

  • 408 Request Timeout

  • 500 Internal Server Error

  • 502 Bad Gateway

  • 503 Service Unavailable

  • 504 Server Timeout

  • 6xx

(Permanent)

  • 401 Unauthorized

  • 403 Forbidden

  • 407 Proxy Authentication Required

  • 4xx, 5xx, 6xx

pjsip.conf :

[74952293042] 
type = registration

;  
;     
retry_interval = 30
;   
max_retries = 100

; "" 
;     403 Forbidden .
forbidden_retry_interval = 300
;     Fatal  (non-temporary 4xx, 5xx, 6xx)
fatal_retry_interval = 300

sip_to_pjsip.py , .

:

  • sip.test.ru

  • sip.test.ru 10.10.10.10

  • 11.11.11.11

  • 10.10.10.10

.

PJSIP IP :

[74952293042]
type = identify
; ... ... ...
match=sip.test.ru,185.45.152.0/24,185.45.155.0/24;
; ... ... ...

"match", , IP . endpoint.

, "endpoint_identifier_order".

:

endpoint_identifier_order=ip,username,anonymous

, IP:PORT, :

endpoint_identifier_order=username,ip,anonymous

, :

  • 99999 - 10.10.10.10:5060

  • 88888 - 10.10.10.10:5060

  • 77777 - 10.10.10.10:5060

"endpoint_identifier_order", :

  • endpoint ( IP:PORT), endpoint "99999" .

  • , endpoint, PJSIP/99999-0000XXX,

SIP URI

.

"res_pjsip_endpoint_identifier_anonymous.so".

pjsip.conf

[anonymous] 
type = endpoint
allow = alaw
timers = no
context = public-direct-dial

extensions.conf

[public-direct-dial]
exten => 74952293042,NoOp(--- Incoming call to ${EXTEN} ---)
	same => n,Dial(PJSIP/204,,TKg));
	same => n,Hangup()

public-direct-dial dialplan.

exten DID .

  • PJSIP . chan_pjsip ,

  • PJSIP

  • PJSIP ,

  • chan_pjsip ,

The disadvantages of switching to chan_pjsip are:

  • Dialplan upgrade required

  • Changing AMI behavior, which affects CTI clients

  • CDR behavior is changing, call history doping needs to be improved

  • chan_pjsip is under active development, there are gross bugs in recent asterisk releases. do not chase new versions, it is better to wait for the appearance of "certified" versions

useful links




All Articles