背景
该材料最初是作为asterconf 2020的报告准备的。现在,我将尝试在本文中更详细地描述所有内容。
MIKOPBX是基于Asterisk 16的免费开源PBX 。一年前,我们开始了向PJSIP的过渡。
主要原因:
PJSIP支持“多重注册”。您可以轻松地在一个帐户上注册多个最终UAC
在一个地址(IP + PORT)上设置多个提供商帐户的注册时,正确处理传入路由的操作
PJSIP的配置更加灵活
chan_sip没有发展,在Asterisk 17中已弃用
接下来,我将描述我们面临的困难和获得的好处。
主要原因是需要支持“多重注册”。将多个软电话/电话连接到您的帐户非常方便,不用担心,无论您身在何处,来电都会到达。
我个人连接了以下设备:
办公室桌面上的硬件电话
笔记本电脑上的软电话
智能手机上的软件电话
当来电到达分机时,所有设备同时振铃。
?
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 ,
切换到chan_pjsip的缺点是:
需要升级Dialplan
更改AMI行为,这会影响CTI客户端
CDR行为正在改变,通话记录掺杂有待改善
chan_pjsip正在积极开发中,最新的星号版本中存在严重的错误。不要追求新版本,最好等待“认证”版本的出现