Cómo traducimos MIKOPBX de chan_sip a PJSIP

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"

Enlaces útiles




All Articles