Antecedentes
El material se preparó originalmente como un informe para asterconf 2020 . Ahora intentaré describir todo con más detalle en este artículo.
MIKOPBX es un PBX de código abierto gratuito basado en Asterisk 16 . Hace un año, iniciamos la transición a PJSIP.
Razones principales:
PJSIP admite " registros múltiples ". Puede registrar fácilmente varios UAC finales en una cuenta
(IP+PORT)
PJSIP
chan_sip deprecated 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 ,
Las desventajas de cambiar a chan_pjsip son:
Requiere actualización de Dialplan
Cambios en el comportamiento de AMI, que se refleja en los clientes de CTI
El comportamiento de CDR está cambiando, el historial de llamadas de dopaje debe mejorarse
chan_pjsip está en desarrollo activo, hay errores graves en las últimas versiones de asterisco. no persiga nuevas versiones, es mejor esperar la aparición de versiones "certificadas"