Il passaggio dalle linee ISDN a trunk ToIP ha provocato qualche problema con alcune funzionalità, tra cui il call deflection. A quanto pare, l’SBC del fornitore del servizio non supportava queste segnalazioni, oltre a supportare solamente il codec G.729.
Ho così implementato un semplice B2BUA con Asterisk, tra l’SBC del fornitore del trunk ToIP e il mio SIP router (OpenSIPS).
Installazione Asterisk 18
Partendo da una Debian 11 x64 su un server virtuale con 10GByte di hard disk, 2 CPU e 2 GByte di RAM, ho installato Asterisk 18 direttamente dal sorgente ufficiale.
Le istruzioni sono qui: Installare Asterisk 18 su Debian 11
Configurazione trunks
Un B2BUA –Back2Back User Agent– è un elemento che si preoccupa di gestire le comunicazioni tra due contesti non eterogenei. In questo caso, Asterisk gestisce i due “leg” delle chiamate sia in entrata che in uscita, su protocollo SIP.
Ho usato il nuovo stack PJSIP e la comoda funzionalità dei wizard per definire i due trunk. Ricordo che i files di configurazione di Asterisk sono, generalmente, nella directory /etc/asterisk.
In pjsip.conf ho definito il trasporto e il binding delle interfacce (la porta di default è la 5060):
[global]
type = global
[transport-udp]
type=transport
protocol=udp ;udp,tcp,tls,ws,wss,flow
bind=0.0.0.0
in pjsip_wizard.conf ho definito i due trunk e i relativi contesti, oltre alla definizione dei codec audio accettati:
[trunk_defaults](!)
type = wizard
transport = transport-udp
endpoint/allow_subscribe = no
aor/qualify_frequency = 30
registration/expiration = 1800
ignore_uri_user_options = yes
has_hint = no
allow_transfer = yes
redirect_method = uri_core
allow_subscribe=no
sends_registrations = no
accepts_registrations = no
sends_auth = no
accepts_auth = no
[toip](trunk_defaults)
endpoint/context = from-toip
endpoint/allow=!all,g729
remote_hosts = [SBC]
[voip](trunk_defaults)
endpoint/context = from-voip
endpoint/allow=!all,g729,g722,alaw,ulaw
remote_hosts = [SIP Router]
in extensions.conf ho definito il semplice dialplan, con qualche istruzione in più per il debugging:
[general]
static=yes
writeprotect=no
clearglobalvars=no
userscontext=default
[globals]
[default]
[from-toip]
; TOIP -> B2BUA -> SIP Router
exten => _+X.,1,Noop("Call from TOIP ${CALLERID(num)} to ${EXTEN}")
exten => _+X.,n,Dial(PJSIP/${EXTEN}@voip)
[from-voip]
; SIP Router -> B2BUA -> TOIP
exten => _0X.,1,Noop("Call from VOIP ${CALLERID(num)} to ${EXTEN}")
exten => _0X.,n,Dial(PJSIP/${EXTEN:1}@toip)
exten => _X.,1,Noop("Local call from VOIP ${CALLERID(num)} to ${EXTEN}")
exten => _X.,n,Dial(PJSIP/${EXTEN}@voip)
exten => asterisk,1,Noop("Asterisk")
Asterisk gestirà come due chiamate “indipendenti” i due leg in entrata e in uscita dai trunk “from-toip” e “from-voip“.
Vale la pena ricordare la sintassi del comando Dial di Asterisk:
Dial(Technology/Resource&[Technology2/Resource2[&...]],[timeout,[options,[URL]]]])
la variabile ${EXTEN} contiene il numero chiamato ed è possibile effettuare qualche operazione di trasformazione su di esso, come ad esempio il cut della prima cifra con :1 (${EXTEN:1}).
Debug
Usando l’utility di diagnostica sngrep (apt install sngrep) si vedranno i due leg distinti:
e dalla console di Asterisk, aumentando sensibilmente il livello di debug e di verbosity a 10 (“core set debug 10” e “core set verbose 10“) si vedrà il flusso e le relative operazioni di bridging:
Conclusioni e suggerimenti
Ho scritto questo articolo perché la configurazione di questo semplice B2BUA mi ha comunque comportato diverse ore di lavoro, sia nell’implementazione iniziale che nel debugging dello stesso. La speranza è che possa essere di aiuto a chi ha la mia stessa esigenza.
Per finire, ringrazio la community di Asterisk per il supporto e i suggerimenti dati, nonché gli sviluppatori del progetto open-source Asterisk.