Mostreremo di seguito come configurare un trunk MessageNet ed un interno telefonico, operando tra essi in diverse condizioni e scenari, ovvero: deviazione chiamata con mantenimento del numero originario, selezione passante in ingresso ed uscita, nonché la gestione del FAX tramite protocollo T38.
- Configurazione con stack chan-sip
- Configurazione (sip.conf)
- Dialplan (extensions.conf)
- Selezione passante in ingresso
- Selezione passante in uscita - Header P-Preferred-Identity o Remote-Party-ID
- Selezione passante in uscita - Display part dell'header "From:" (displayname)
- Deviazione pilotata dal PBX con mantenimento del numero chiamante
- NAT traversal
- Invio e Ricezione FAX in T38
Configurazione con stack Chan_SIP
Facciamo presente che non è consigliabile per le nuove installazioni utilizzare chan_sip in quanto chan_sip è stato deprecato in Asterisk 17, per essere rimosso in Asterisk 21.
Come esempio, consideriamo una configurazione aperta generica sul realm di MessageNet, che abilita i codec standard ST-769, sotto NAT, dove il context inbound è inbound_context ed un Account VoIP 5xxxxxx con password yyyyyyy che definirà una register con extension NUMERONELDIALPLAN ed un peer 5xxxxxx-messagenet per le chiamate in uscita nel contesto outgoing_context.
Configureremo inoltre un interno 244 per esemplificare una configurazione funzionante.
Configurazione sip.conf
[general]
bindaddr=0.0.0.0:5060 ; bind UDP 5060 from any IP source
context=inbound_context
nat=force_rport,comedia
disallow=all
;allow=g729:20 ; commented: you need g729 license allow=alaw:20
realm=sip.messagenet.it
rtptimeout=60
rtpholdtimeout=300;
;incoming calls (register)
register => 5xxxxxx:yyyyyyy@sip.messagenet.it:5061/NUMERONELDIALPLAN;
;outgoing calls type (peer)
[5xxxxxx-messagenet]
username = 5xxxxxx
fromuser = 5xxxxxx
secret = yyyyyyy
host = sip.messagenet.it
port = 5061 ; 5060 or 5061 for plain UDP in Messagenet
qualify = yes
insecure = invite,port;
ferle
;internal peer
[244]
type=peer
language=it
qualify=yes
qualifyfreq=60
nat=no ; there is no NAT here
host=dynamic
context=outgoing_context
secret=ciaociao
callerid=Pinco Pallino
dtmfmode=rfc2833
directmedia=no
disallow=all
;allow=g729:20 ; commented: you need g729 license
allow=alaw:20
Dialplan (extensions.conf)
Seguendo l’esempio, definiamo due contesti:
- inbound_context per l’ingresso (che inoltra quanto ricevuto da MessageNet all’interno, senza tenere conto di altro)
- outgoing_context per l’uscita (che inoltra via MessageNet la chiamata, se effettuata verso un numero fisso o mobile nazionale)
; inbound context [inbound_context]
exten => _NUMERONELDIALPLAN,1,Dial(SIP/244)
; outgoing context
[outgoing_context]
exten => 03].,1,Dial(SIP/${EXTEN}@5xxxxxx-messagenet)
Selezione Passante in ingresso
Si faccia riferimento all’articolo Un solo Account VoIP con più numeri geografici su Helpcenter MessageNet: in breve, il numero chiamato è indicato in formato nazionale nella user-part dell’header “To:” e qui può essere letto ed impiegato nella logica del nostro PBX.
Si ipotizzi, ad esempio, di aver abilitato i numeri 021234567 e 061234567 sulla medesima utenza 5xxxxxx e di voler distinguere le chiamate sulla base del numero chiamato.
Nel file sip.conf potremmo quindi avere:
register => 5xxxxxx:password@sip.messagenet.it:5061/200
Dove nel nostro caso 200 è l'estensione locale con la quale le chiamate verranno gestite lungo il context relativo a questa richiesta di registrazione al servizio.
Nel dialplan definiremo quindi l’extension 200 che opererà in modo da discriminare le chiamate; un esempio di come farlo è il seguente, basato sulla lettura dell’header e sull’estrapolazione della user-part in una variabile CALLED che verrà poi impiegata in seguito:
[inbound_context]exten => 200,1,Set(CALLED=${CUT(CUT(SIP_HEADER(TO),@,1),:,2)})exten => 200,n,Verbose(Chiamata per il numero ${CALLED})exten => 200,n,GotoIf($["${CALLED}" == "0612345678"]?to-rome,s,1)exten => 200,n,GotoIf($["${CALLED}" == "0212345678"]?to-milan,s,1)exten => 200,n,GotoIf($["${CALLED}" == "5312345"]?to-internal,s,1)exten => 200,n,Goto(to-other,s,1)
[to-rome]exten => s,1,Verbose(Chiamata per Roma)exten => s,n,Dial(SIP/201) ; inoltro chiamata al peer 201exten => s,n,Hangup()
[to-milan]exten => s,1,Verbose(Chiamata per Milano)exten => s,n,Dial(SIP/202) ; inoltro chiamata al peer 202
exten => s,n,Hangup()
[to-internal]exten => s,1,Verbose(Chiamata per Numero Interno Messagenet - URI)exten => s,n,Dial(SIP/203) ; inoltro chiamata al peer 203
exten => s,n,Hangup()
[to-other]exten => s,1,Verbose(Chiamata per numero non configurato)exten => s,n,Playback(pbx-invalid)
exten => s,n,Hangup()
Selezione Passante in uscita – Header P-Preferred-Identity o Remote-Party-ID
Si faccia riferimento all’articolo Un solo Account VoIP con più numeri geografici su Helpcenter MessageNet: in breve, la feature è disponibile tramite diversi header ma deve essere abilitata specificamente sull’URI in questione.
Si ipotizzi di aver abilitato i numeri 021234567 e 061234567 sulla medesima utenza 5xxxxxx e di voler chiamare il numero 3212345678 percorrendo l’estensione ext nel dialplan:
...
exten => ext,n,Dial(SIP/5xxxxxx/3212345678)
...
exten => h,1,HangUp()
Si vuole scegliere quale dei due numeri mostrare al chiamato e per questo fine si scelga di aggiungere con una priorità precedente (qui scriviamo n-1 e n-2 unicamente per maggiore comprensione) alla Dial() un'altra direttiva SipAddHeader: exten => h,1,HangUp() Con questo setup la chiamata andrà su rete telefonica con CLI 021234567
Selezione Passante in uscita – display part dell'header "From:" (displayname)
Si faccia riferimento all’articolo Un solo Account VoIP con più numeri geografici su Helpcenter MessageNet: in breve, la feature è disponibile tramite diversi header ma deve essere abilitata specificamente sull’URI in questione. Si ipotizzi di aver abilitato i numeri 021234567 e 061234567 sulla medesima utenza 5xxxxxx e di voler chiamare il numero 3212345678 percorrendo l’estensione ext nel dialplan; il dialplan sarà così modificato:
...
exten => ext,n-1,Set(CALLERID(name)="+39061234567")
exten => ext,n,Dial(SIP/5xxxxxx/3212345678)
...
exten => h,1,HangUp()
Con questo setup la chiamata andrà su rete telefonica con CLI 021234567.
Deviazione pilotata dal PBX con mantenimento del numero chiamante
Si faccia riferimento all’articolo Deviazione di Chiamata tramite apparato esterno su Helpcenter MessageNet: in breve, la feature è realizzata riproponendo nella chiamata in uscita l’header X-Mnet-InLeg atto a screening. Di seguito, come apparirebbero le istruzione indicate in uno snippet di esempio di extensions.conf nell’estensione s del contesto opportuno:
exten => s,n,...
exten => s,n,SipAddHeader(X-Mnet-InLeg: ${SIP_HEADER(X-Mnet-InLeg)})
exten => s,n,Playback(beep) ; Vedi Nota Bene
exten => s,n,Dial(...)
N.B.: nell’esempio sopra abbiamo preposto alla Dial() una Playback() atta sostanzialmente a rilasciare dell’RTP verso il chiamato, non necessariamente con audio udibile (potrebbe essere un file di silenzio); tale soluzione viene utilizzata per sollecitare la sessione NAT necessaria all’RTP in una condizione dove il PBX non emette RTP fino a che non ne riceve dalla destinazione chiamata
NAT traversal
In generale, non è mai necessario configurare DMZ o port-forwarding statici (che si baserebbero per altro su situazioni di NAT della porta simmetriche o predicibili, e non sempre è così): si consiglia pertanto di mantenere dietro NAT il PBX demandando alle funzionalità di NATP dinamico dell’apparato di rete la definizione delle sessioni necessarie alla comunicazione.
Per mantenere funzionale questa configurazione, è utile tenere in considerazione che a seconda del trasporto scelto, dall’intervallo di ri-registrazione al servizio o al keep-alive impostato, derivano caratteristiche della NAT diverse (tipicamente su TCP avremo masquerading della porta) o conseguenze operative (chiusura della sessione anzitempo) che devono essere tenute in considerazione ed ottimizzate.
Tenendo quindi in considerazione la configurazione esemplificata in precedenza, in caso di problemi nella registrazione al servizio o nella gestione della comunicazione SIP, è opportuno verificare se l’impiego di TCP quale trasporto possa risolvere tali problematiche (tipicamente legate alla sessione NAT od alla frammentazione IP):
;;;;;;; sip.conf ;;;;;;; [general] [...] defaultexpiry=300 ; in order to avoid NAT traversal issues
tcpenable=yes tcpbindaddr=0.0.0.0:5060 ; must not conflict with other binds! tcpauthtimeout=30 tcpauthlimit=100 [...]
; incoming calls (TCP register (extension = s) every 180 seconds)
register => tcp://5xxxxxx:yyyyyyy@sip.messagenet.it~180;
outgoing calls type (peer)
[5xxxxxx-messagenet]
auth = md5
username = 5xxxxxx
fromuser = 5xxxxxx
secret = yyyyyyy
transport = tcp ; in order to avoid NAT traversal issues
host = sip.messagenet.it
port = 5060 ; 5060 for TCP Transport in Messagenet
qualify = yes ; keep-alive to avoid NAT traversal issues qualifyfreq = 30 ; keep-alive to avoid NAT traversal issues
insecure = invite,port
Si ribadisce che qui sono in gioco due flussi: da un lato c’è la registrazione al servizio, dall’altra il peer chiamante: questi due oggetti possono essere configurati diversamente, e sono appunto distinti.
Nel momento in cui il problema si presenta come indisponibilità randomica, senza errori nella registrazione al servizio, la comunicazione avviene correttamente, ma la sessione NAT dura troppo poco: nei nostri template abbiamo sempre indicato un lease di registrazione basso (300 secondi) con keep-alive attivo (qualify e qualifyfreq). Si può ottimizzare riducendo questo valore (nel caso sopra è stato aggiunto il parametro ~180 alla register) o incrementando la durata della sessione NAT sul router.
Invio e Ricezione FAX in T38
Asterisk consente di inviare e ricevere FAX tramite un opportuno DSP (fisico o virtuale) e l’estensione T38 del protocollo SIP.
Procederemo impiegando span_dsp come risorsa per la ricezione e l’invio del fax (tramite immagini TIFF) e configureremo il T38 in modo tale da utilizzare redundancy quale EC mode.
https://www.soft-switch.org/ (viene distribuito assieme al PBX stesso)
;;; sip.conf ;;; [general] ...
t38pt_udptl=yes,redundancy ; No FEC, use redundancy! faxdetect=yes ; enables both CNG and T.38 detection
Nel momento in cui la risorsa è correttamente caricata e configurata, possiamo definire a dialplan opportuni contesti per la ricezione e l’invio, come qui esemplificato:
;;;; INVIO ;;;;
; definiamo un contesto SendFax dove,
; alla stregua degli esempi originali,
; il nostro URI instaura una chiamata
; e tramite un hook post-dial andrà ad
; invocare l’app SendFax sull’estensione `s`
[SendFax]
exten => _X!,1,Set(CALLERID(num)=5XXXXX)
exten => _X!,n,Set(SIPDOMAIN=${MNet_REALM})
exten => _X!,n,Dial(SIP/${EXTEN}@messagenet-5XXXXX,,TWG(s^1),)
exten => s,1,HangUp()
exten => s,n,NoOp("TESTFAX starts")
exten => s,n,SendFax(/tmp/${FAXFILE}.tif,dfzs)
exten => s,n,NoOp(FAXstatus ${FAXOPT(status)})
;;;; RICEZIONE ;;;;
; salviamo nella directory /tmp il file ricevuto,
; nominandolo in base alla data ed ora di ricezione
; `fax` è il nome dell’estensione usata in caso di
; tono CNG o re-INVITE in udptl (vedi sip.conf)
; NOTE: the channel must be answered in order to switch here!
[inbound_context]
exten => fax,1,NoOp("Incoming FAX Transmission")
exten => fax,n,Set(NAME=/tmp/fax_${STRFTIME(,,%C%y%m%d%H%M)}.tif)
exten => fax,n,ReceiveFax(${NAME},dfs)