Configuration d'asterisk PBX

Introduction

Après avoir installé Asterisk, il faut encore le configurer. Cette configuration dépend de plusieurs paramètres entre autres: elle est l'image de votre réseau, elle dépend fortement de la version d'Asterisk utilisé (ici la version 11). En conséquence, il est important de comprendre les mécanismes de configuration pour pouvoir les utiliser et éventuellement les aménager pour votre propre solution.

Mots spécfiques à asterisk

Certains mots ont un sens particulier dans le contexte asterisk: en voici une liste non exhautive.

Liste des fichiers de configuration

Les fichiers de configuration d' asterisk sont installés dans le répertoire /etc/asterisk si on n'a pas modifié la configuration de compilation par default.

root@pi /etc/asterisk # ls
acl.conf              confbridge.conf   queues.conf
agents.conf           ext_torture.conf  res_config_sqlite3.conf
asterisk.conf         extensions.conf   res_fax.conf
calendar.conf         features.conf     res_odbc.conf
ccss.conf             http.conf         rtp.conf
cdr.conf              iax.conf          sip.conf
cdr_custom.conf       indications.conf  sip_linphone.conf
cdr_odbc.conf         logger.conf       sip_ovh.conf
cdr_syslog.conf       manager.conf      smdi.conf
cel_custom.conf       modules.conf      udptl.conf
cel_odbc.conf         musiconhold.conf  voicemail.conf
cli_permissions.conf  queuerules.conf

Plutôt que d'installer tous les fichiers configs/*.sample de la distribution, il est préférable d'installer les indispensables, comme asterisk.conf, indications.conf, modules.conf, musiconhold.conf , puis de consulter le fichier log d'asterisk et d'installer, même vide, les fichiers pour lesquels asterisk se plaint. Ici par exemple, les fichiers confbridge.conf agents.conf cdr_odbc.conf acl.conf res_fax.conf res_odbc.conf ccss.conf udptl.conf smdi.conf cel_custom.conf res_config_sqlite3.conf queuerules.conf cel_odbc.conf calendar.conf sont vides.

A noter que, dans les fichiers de configuration, le ; commence un commentaire donc tout ce qui se trouve après est ignoré.

Ce que fait Asterisk

Votre téléphone est connecté au BX (branch exchange en français: autocom) de votre fournisseur. Vous ne pouvez faire aucune action sur ce BX sinon que d'accepter ou refuser l'appel, mais quand celui ci arrive, c'est déjà trop tard: vous avez été dérangé...

Avec un PBX (Private branch exchange) comme Asterisk, que vous êtes le seul à contrôler et que vous intercalez entre votre téléphone et le BX du fournisseur, les appels entrants sont traités suivant la programmation que vous avez fait dans extensions.conf et transmis à votre téléphone si les conditions sont satisfaites : silence assuré !

Configuration du réseau

Les fichiers qui définissent la configuration du réseau sont les fichiers sip.conf et extensions.conf. Inutilisé ici, au même niveau que sip.conf, on pourrait trouver un fichier iax.conf pour des liaisons de type IAX, et chan_dahdi.conf pour le branchement de téléphones analogiques par l'intermédiaire d'une carte PCI incorporée à un pc.

Asterisk met en relation 2 branches de communication (2 bras ou 2 jambes suivant les préférences !). Ces branches de communication, une entrante et une sortante, passent par sip.conf et sont mis en relation dans le dialplan extensions.conf, le noeud du système.

Pour prendre un exemple, une liaison SIP de poste à poste, émanant du client SIP sur mon PC et appelant le poste 602, va entrer dans le contexte soft-sip-hq parce que le client SIP a été configuré avec ces paramètres. Elle va ensuite être redirigée vers le contexte User-super de extensions.conf qui inclus le contexte User-standard, qui inclus le contexte User-internal, qui inclus le contexte LocalSets. Dans LocalSets, l'extension 602 va faire un Dial vers l'extension soft-sip-fq qui se trouve aussi dans le fichier sip.conf et qui va contacter le client qui s'est enregistré avec les paramètres de soft-sip-fq, c'est la branche de sortie. La mise en relation est faite par le Dial.

Fichier sip.conf

Le fichier sip.conf commence, comme à peu près tous les fichiers de configuration, par un contexte general dont les variables sont applicables à tous les autres contextes du fichier, excepté lorsqu'elles sont redéfinies.

;
; sip.conf
;

[general]
context = unauthenticated         ; default context for incoming calls
allowguest = no                   ; disable unauthenticated calls
alwaysauthreject = yes
srvlookup = yes                   ; enable DNS SRV record lookup on outbound calls

udpbindaddr = 0.0.0.0             ; listen for UDP requests on all interfaces
tcpenable = no                    ; disable TCP support

; bindport = 5061

disallow = all
allow = ulaw
allow = alaw
allow = gsm

qualify = yes
host = pi.noz

dtmfmode = auto
language = fr
callcounter = yes ; enable device states for SIP device
Soft phone

Ensuite on définit un template, c'est à dire un groupe de variables qui va être appliqué aux contextes pour les softphones.

[soft-phone](!)                 ; create a template for our devices
type = friend                   ; the channel driver will match on username first, IP second
context = LocalSets             ; this is where calls from the device will enter the dialplan
host = dynamic                  ; the device will register with asterisk
; nat = force_rport,comedia       ; assume device is behind NAT
nat = no
dtmfmode = auto                 ; accept touch-tones from the devices, negotiate d automatically
disallow = all                  ; reset which voice codecs this device will accept or offer
allow = ulaw                    ; in the order we prefer
allow = alaw
allow = gsm
allow = g722                    ; audio codecs to accept from, and request to, the device

Les contextes suivants définissent la configuration Asterisk pour les softphones comme ekiga ou linphone. Ces softphones doivent aussi être configurés pour se connecter à asterisk, l'identificateur étant le nom du contexte et le mot de passe la variable secret. Les contextes sont à la fois entrant et sortant.

Le téléphone DECT est branché sur le port FXS du SPA 3102. Le réseau commuté RTC est branché sur le port FXO du SPA 3102. Ils ont, tous les 2, quelques pages de configuration. Ils se comportent comme des soft-phone du coté Asterisk.

Une petite note au sujet du SPA 3102 et des appels entrants: lors d'un appel entrant le premier à travailler c'est le SPA. Quand il contacte Asterisk, il ne faut pas que le réseau (routeur, Archlinux, Asterisk) soit "endormi", car on risque de perdre l'appel. Dans certains cas, ce n'est pas trop grave, mais cela fait désordre, en effet l'appelant croyant avoir fait une erreur, rappelle aussitot et alors l'appel est correctement traité.

Pour maintenir le réseau éveillé, il faut, dans la configuration du SPA, régler la variable Register Expires: à 120 secondes et non pas 1200 ou 3600 secondes. Ainsi le SPA n'a pas besoin de demander au réseau qui a l'adresse IP 192.168.1.xx.

Un autre point concernant la variable Ring Timeout: dans PSTN line / International control, elle avait pour valeur 640 ms et il me fallait, toujours ou presque, répéter la numérotation pour un appel sortant. J'ai vu quelqu'un qui disait devoir la mettre à 1536 ms pour que ça marche. J'ai donc essayer cette valeur et là, du coup, aucun n'appel n'aboutissait, ce qui montre que cette variable est sensible au probléme de numérotation. J'ai donc fixé la valeur à 256 ms (certains mettent 128 ms) et pour l'instant il n'y a pas eu d'échec.

Dans chaque contexte, on trouve une variable context. La valeur de cette variable est le nom du contexte point d'entrée dans le fichier extensions.conf.

; define a device name and use the office-phone template
[soft-sip-hq](soft-phone)
secret = un_mot_de_passe
description = soft phone sip for hq
context = User-super
callerid =''Hervé'' <601>

[soft-sip-fq](soft-phone)
secret = un_mot_de_passe
description = soft phone sip for fq
context = User-standard
callerid =''Francoise'' <602>

[soft-sip-mq](soft-phone)
secret = un_mot_de_passe
description = soft phone sip for mq
context = User-internal
callerid =''Maureen'' <603>

[sip-dect](soft-phone)  ; tel dect sur spa3102
secret = un_mot_de_passe
description = tel dect sur spa3102
context = User-standard

[sip-pstn](soft-phone)  ; tel rtc sur spa3102
secret = un_mot_de_passe
description = tel rtc sur spa3102
context = From-Pstn
authuser = sip-pstn
defaultuser = sip-pstn
; dtmfmode = INFO 

La ligne RTC est devenue, avec le temps, une ligne Livebox qui est, en fait, une ligne SIP un peu spéciale. Ce montage est donc une aberration parce que l'on passe du SIP à analogique pour repasser immédiatement en SIP. Une liaison directe SIP serait plus adéquate, mais il n'est pas question de fournir les paramètres de connection SIP pour notre opérateur qui ne croit en sa survie qu'avec des solutions propriétaires bien fermées plutôt que des solutions ouvertes et open sources. L'avenir nous dira si il a raison.

La solution est toutefois suffisante pour garder nos téléharceleurs out of the field.

Ligne sip Linphone

Une ligne sip Linphone est gratuite et permet des communications SIP entre clients enregistrés Linphone ou interdomaine sip, ce qui est bien utile pour les tests de mise au point.

Le contexte est enregistré dans un fichier séparé et inclus dans le fichier sip.conf par une directive include, ce qui permet de l'activer/désactiver en décommentant / commentant la directive include. Attention, cependant, la directive register doit se trouver dans le contexte general de sip.conf.

#include "sip_linphone.conf"
register => user_linphone:password_linphone@sip.linphone.org:5060

; Création du compte Asterisk pour linphone
[sip-linphone](!)                 ; create a template for our devices
description = ligne sip vers linphone
type = friend
host = sip.linphone.org
port = 5060
defaultuser = user_linphone      ; defaultuser replace username
secret = password_linphone
fromdomain = sip.linphone.org
fromuser = user_linphone
nat = force_rport,comedia       ; assume device is behind NAT
insecure = invite,port
qualify = yes
dtmfmode = inband
defaultexpiry = 3600
registertimeout = 120
localnet = 192.168.1.0/255.255.255.0

[Vers-Linphone](sip-linphone)
context = From-Linphone    ; received call from linphone go to  From-Linphone context
ligne sip OVH

Même remarque que pour sip_linphone.conf. Le contexte est enregistré dans un fichier séparé sip_ovh.conf.

#include "sip_ovh.conf"
register => 0033972xxxxxx:mot-de-passe-ovh@sip.ovh.fr:5962


; Création du compte Asterisk pour Ovh
[sip-ovh](!)                 ; create a template for our devices
description = ligne sip ovh
type = friend
secret = mot-de-passe-ovh
host = sip.ovh.fr
port = 5962
fromdomain = sip.ovh.fr
fromuser = 0033972xxxxxx
defaultuser = 0033972xxxxxx
nat = force_rport,comedia       ; assume device is behind NAT
insecure = invite,port
qualify = yes
dtmfmode = inband
defaultexpiry = 3600
registertimeout = 120
localnet = 192.168.1.0/255.255.255.0

; Création du compte Asterisk pour OVH
[Vers-Ovh](sip-ovh)

[Depuis-Ovh](sip-ovh)
md5secret = 226ea6cf875d66b15d275684427214bb
context = From-Ovh

La configuration Ovh nécessite 2 contextes un pour l'entrée, l'autre pour la sortie, la différence étant le champ md5secret qui se calcule comme ceci, en remplacant le userid et le mot de passe par leur valeurs respectives:

echo -n "0033972xxxxxx:asterisk:mot-de-passe-ovh" | md5sum
226ea6cf875d66b15d275684427214bb  -

Fichier extensions.conf

Ce fichier définit le diaplan ou plan de numérotation.

Ce fichier commence par le contexte general qui définit quelques variables globales.

;
; extensions.conf : used by the pbx_config module.
;

[general]
static = yes
writeprotect = no
autofallthrough = yes
clearglobalvars = yes
;userscontext = default           ; voir users.conf

[globals]                 ; Variables globales
DIAL_OPTS = gtTmXx        ; options de Dial par defaults
MY_DIAL_STATUS = ANSWER

LigneFT = SIP/sip-pstn
LigneSip = SIP/Vers-Ovh
TIMEOUT = 45

#include "ext_torture.conf"

Ce fichier ext_torture.conf est inséré ici par un include, ce qui permet de le désactiver facilement. C'est un bon exemple de programmation sous Asterisk, mais ce n'est pas essentiel pour le fonctionnent de votre pbx.

;
; ext_torture.conf
;

[torture]
exten => s,1,Set(CHANNEL(language)=fr)
    same => n,PlayBack(wait-moment)
    same => n,Set(FINIR=0)
    same => n(loop),Wait(3)
    same => n,Set(FINIR=$[${FINIR} + 1])
    same => n,NoOp(${FINIR})
    same => n,Background(ask-to-dinner&silence/3)
    same => n,ExecIf($["${FINIR}"="8"]?HangUp() ;au bout de 8 tour de menu on raccroche
    same => n,Goto(torture,s,loop)

exten=>1,1,Goto(torture1,s,1) ; service vente
exten=>2,1,Goto(torture2,s,1) ; service support technique
exten=>3,1,Goto(torture3,s,1); pdg
exten=>4,1,Goto(torture4,s,1); dinner

[torture1]
exten => s,1,Wait(1)
    same => n,PlayBack(queue-periodic-announce)
    same => n,MusicOnHold(default,15)
    same => n,Wait(1)
    same => n,PlayBack(queue-periodic-announce)
    same => n,MusicOnHold(default,15)
    same => n,Wait(1)
;    same => n,PlayBack(estimated-holdtime,20)
;    same => n,Playback(abandon-all-hope,20)
    same => n,PlayBack(an-error-has-occured)
    same => n,PlayBack(cannot-complete-temp-error)
    same => n,GoTo(torture,s,loop)

[torture2]
exten => s,1,Wait(1)
    same => n,PlayBack(busy-pls-hold)
    same => n,MusicOnHold(default,20)
    same => n,Wait(1)
    same => n,PlayBack(blue-eyed-polar-bear)
    same => n,MusicOnHold(default,20)
    same => n,Wait(1)
    same => n,PlayBack(never-reach-them)
    same => n,Wait(1)
    same => n,GoTo(torture,s,loop)

[torture3]
exten => s,1,Wait(1)
    same => n,PlayBack(not-taking-your-call)
;    same => n,PlayBack(away-naughty-girl)
    same => n,Wait(1)
    same => n,PlayBack(privacy-if-sales-call-contact-in-writing)
    same => n,Goto(torture,s,loop)

[torture4]
exten=>s,1,Wait(1)
    same => n,PlayBack(go-away1)
;    same => n,PlayBack(go-away2)
    same => n,Goto(torture,s,loop)

Le contexte LocalSets contient les extensions locales. Toute la problématique de ce fichier extensions.conf c'est de pouvoir analyser les nuérotations le plus simplement possible pour les diriger vers leur destination respective. La tranche 600 - 699 est ainsi réservée à l'utilisation locale puisqu'aucun autre numéro ne commencant par 6 et que 100 numéros sont plus que suffisant.

[LocalSets]
exten => 601,1,GoSub(subDialVm,start,1(SIP/soft-sip-hq,${EXTEN}))
exten => 602,1,GoSub(subDialVm,start,1(SIP/soft-sip-fq,${EXTEN}))
exten => 603,1,GoSub(subDialVm,start,1(SIP/soft-sip-mq,${EXTEN})) 

exten => 609,1,NoOp(SIP/Vers-Linphone) 
    same => n,Set(CALLERID(name)=herveq)
    same => n,Dial(SIP/Vers-Linphone/fanfan52, 30, ${DIAL_OPTS} )

exten => 610,1,GoSub(subDialVm,start,1(SIP/sip-dect,${EXTEN})) 

exten => 611,1,Answer ;
    same => n,Goto(who-r-u,s,1)

;exten => 666,1,Goto(torture,s,1) 

exten => 667,1,NoOp(Access voicemail retrieval.)
    same => n,VoiceMailMain()

exten => 690,1,Goto(From-Pstn,666,1) ; test gotoif time

;
; Horloge
exten => 696,1,Answer()
    same => n,Set(CHANNEL(language)=fr)
    same => n,Playback(welcome)
    same => n,SayUnixTime(,Europe/Paris,AdBY kM)
    same => n,Playback(vm-goodbye)
    same => n,Hangup()

; test music on hold
;
exten => 697,1,Answer()
    same => n,SetMusicOnHold(default)
    same => n,MusicOnHold()
    same => n,Hangup()

exten => 698,1,Answer()
     same => n,Playback(hello-world)
     same => n,Hangup()

; Faites le 699 pour faire un "Echo test"
exten => 699,1,Ringing()                        ; Juste pour le fun
     same => n,Wait(3)
     same => n,Set(CHANNEL(language)=fr)
     same => n,Playback(demo-echotest)          ; Présentation du test
     same => n,Echo()                           ; Le test proprement dit
     same => n,Playback(demo-echodone)          ; C'est fini'
     same => n,Hangup()

Plutôt que de faire sonner immédiatement un poste, il peut être préférable de laisser l'appelant choisir entre laisser un message ou entrer en relation. C'est par exemple, le cas du dentiste qui vous rappelle un rendez vous pris 4 semaines plus tôt.

[Accueil]
exten => start,1,NoOp()
    same => n,Wait(4)
    same => n,Answer()
    same => n,Set(COUNT=0)
    same => n,Background(hq-hello)
    same => n,Set(CHANNEL(language)=fr)
    same => n(menu-accueil),Background(vm-leavemsg&hq-relation)
    same => n,WaitExten(3)
    same => n,Background(vm-sorry&silence/5)
    same => n,Set(COUNT=$[${COUNT} + 1])
    same => n,ExecIf($["${COUNT}"="10"]?Goto(finish) 
    same => n,Goto(menu-accueil)
    same => n(finish),Playback(were-sorry)
    same => n,HangUp() 
    
exten => 1,1,Goto(From-Pstn,666,pstn-dial)
exten => 5,1,Goto(From-Pstn,666,pstn-vm)
exten => 2,1,Playback(spam&silence/5)
    same => n,Goto(accueil-exit)
exten => 3,1,Playback(priv-callee-options&silence/5)
    same => n,Goto(accueil-exit)
exten => 4,1,Playback(never-reach-them&silence/5)
    same => n,Goto(accueil-exit)
exten => 6,1,Playback(privacy-if-sales-call-contact-in-writing&silence/5)
    same => n,Hangup()

exten => i,1,Playback(pbx-invalid)
    same => n,Goto(Accueil,start,menu-accueil)
exten => t,1,Playback(vm-goodbye)
    same => n,Hangup

[who-r-u]
exten => s,1,Background(privacy-unident)
    same => n,Background(vm-rec-name)
    same => n,Wait(1)
    same => n,Record(/tmp/ast-stranger:ulaw,5,15)
    same => n,Background(pls-hold-while-try)
    same => n,Goto(parkedcalls,600,1)
;    same => n,VoiceMail(2001@default)
    same => n,Playback(vm-goodbye)
    same => n,Hangup()

[parkedcalls]
exten => 600,1,NoOp()
    same => n,SetMusicOnHold(default)
    same => n,ParkAndAnnounce(asterisk-friend:/tmp/ast-stranger:vm-isonphone:at-followingnumber:PARKED,40,SIP/soft-sip-fq,who-r-u,s,7)
    same => n,Hangup()

[parkedcalls-pick]
exten => _64X,1,Pickup(${EXTEN})
    same => n,Hangup()

Les contextes suivants traitent la numérotation : urgence, numéros spéciaux, appels vers portables, appels nationaux, appels vers l'internationnal. Je suppose que l'on doit pouvoir faire plus simple, mais il me semble utile de pouvoir choisir le chemin de sortie pour certaines destinations. les instructions NoOp ne sont là que pour afficher les numéros dans la console Asterisk.

; ###############   Contextes des destinations externes ################
; call to external word
[ext_urgence]
                 ; 15, 17, 18   SAMU, police secours, pompiers
exten => _1[578],1,NoOp(${LigneFT}/2U_${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Dial(${LigneFT}/${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Congestion(3)

         ; 112, 115, 119 urgence europe, SAMU Social, enfance maltraitée
exten => _11[259],1,NoOp(${LigneSip}/3U${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Dial(${LigneFT}/${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})

[ext_short]
exten => _1[06]XX,1,NoOp(${LigneSip}/1S${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Dial(${LigneSip}/${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
exten => _3XXX,1,NoOp(${LigneFT}/3S_${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Dial(${LigneFT}/${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
exten => _11[68]XXX,1,NoOp(${LigneSip}/6S_${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Dial(${LigneSip}/${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})

[ext_portable]
exten => _0[67]X.,1,NoOp(${LigneFT}/P_${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Dial(${LigneFT}/${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Congestion(3)

[ext_nationnal]
exten => _0ZX.,1,NoOp(${LigneSip}/N_${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Set(TIMEOUT(absolute)=3300); 
    same => n,Dial(${LigneSip}/${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Congestion(3)

[ext_internationnal]
exten => _00ZX.,1,NoOp(${LigneSip}/EI${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Set(TIMEOUT(absolute)=3300); 
    same => n,,Dial(${LigneSip}/${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Congestion(3)

[ext_nationnal_ft]
exten => _9ZX.,1,NoOp(${LigneFT}/FN_0${EXTEN:1}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Dial(${LigneFT}/0${EXTEN:1}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Congestion(3)

[ext_internationnal_ft]
exten => _90ZX.,1,NoOp(${LigneFT}/FEI_0${EXTEN:1}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Dial(${LigneFT}/0${EXTEN:1}, ${TIMEOUT}, ${DIAL_OPTS})
    same => n,Congestion(3)


exten => i,1,Playback(pbx-invalid)
    same => n,Goto(TestMenu,start,1)

L'instruction Gosub est en fait un sous programme et a pour but de simplifier l'écriture. Ici la réponse de la commande Dial est testée, si le poste n'a pas répondu, parce qu'il est occupé ou absent, l'appelant est dirigé vers la messagerie vocale.

; ###############   Contextes Gosub ################

[subDialer]
exten => start,1,NoOp()
    same => n,Dial(${ARG1},${ARG2},${DIAL_OPTS})
    same => n,Return(${DIALSTATUS})

[subVoicemail]
exten => start,1,NoOp()            ; vmbox, context, dialStatus
    same => n,GotoIf($["${ARG3}" = "ANSWER"]?VmOk)
    same => n,Set(VmMessage=${IF($[${ARG3} = BUSY]?b:u)})
    same => n(VmOk),VoiceMail(${ARG1}@${ARG2},${VmMessage})
    same => n,Hangup()

[subDialVm]
exten => start,1,NoOp()
    same => n,GoSub(subDialer,start,1(${ARG1},30))
    same => n,GotoIf($["${GOSUB_RETVAL}" = "ANSWER"]?DialOk)
    same => n,GoSub(subVoicemail,start,1(${ARG2},default,${GOSUB_RETVAL}))
    same => n(DialOk),Hangup()

[TestsubDialVm]
exten => start,1,NoOp()
    same => n,Answer()
    same => n,SayDigits(${ARG2}&silence/1)
    same => n,Hangup()

; ###############   Contextes des destinations ################
[myparkedcalls]
; Touche Transfert puis *3 alors Asterisk rappelle pour annoncer la place de parking
exten => _*3,1,ParkAndAnnounce(pbx-transfer:PARKED|120|SIP/${DIALEDPEERNUMBER}|default,${DIALEDPEERNUMBER},1)

; ##################  Contextes des Services utilisateur ######################
[Services-util]
exten => *1,1,NoOp(Access voicemail retrieval.)
    same => n,VoiceMailMain(${CALLERID(num)}@default,s)

; ##################  Contextes des Services Admin ######################
[Services-admin]
exten => *98,1,NoOp(Access voicemail retrieval.)
    same => n,VoiceMailMain(${CALLERID(num)}@default,s)

Les contextes utilisateurs permettent de donner plus ou moins de droits aux utilisateurs. Ce n'est que pour la beauté de la chose !

; ##################  Contextes des utilisateurs ######################
   
[User-internal]
include => parkedcalls-pick
include => LocalSets
include => ext_urgence
include => Services-util

[User-standard]
include => User-internal
include => ext_short
include => ext_portable
include => ext_nationnal
include => ext_internationnal
include => ext_nationnal_ft
include => ext_internationnal_ft

[User-super]
include => User-standard
include => Services-admin

Le contexte From-Pstn est sans doute le plus important de la configuration. c'est ici qu'arrivent les appels en provenance de la ligne fixe. Il permet de faire une sélection à l'arrivée, et je vous laisse deviner pourquoi.

La première décision concerne les appels masqués, ils sont renvoyés vers l'étiquette masqued_call. Pour comprendre, il faut savoir que le spa3102 renvoie son propre identifiant (ici sip-pstn), lorsque l'identifiant de l'appelant n'est pas renseigné, autrement dit lorsqu'il est masqué.

Ensuite on exécute un programme telnumck (voir sa description plus bas) qui examine le numéro d'appel. Si le numéro fait partie de la liste blanche, l'appel est redirigé vers le poste associé. Si le numéro fait partie de la liste noire, l'appel est redirigé vers l'étiquette blacklisted. Dans les autres cas, l'appel est redirigé vers l'accueil.

[From-Pstn]
exten => 666,1,Noop(${CALLERID(num)}, ${CALLERID(name)})
    same => n,GotoIf($["${CALLERID(num)}" = "sip-pstn"]?masqued_call)
    same => n,Set(TESTNUM=${SHELL(/usr/bin/telnumck ${CALLERID(num)}):0:-1})
    same => n,GotoIf($["${TESTNUM}" = "Wok"]?pstn-dial)
    same => n,GotoIf($["${TESTNUM}" = "Bok"]?blacklisted)
    same => n,Set(DIAL_OPTS=gtmx)
    same => n,Set(TIMEOUT(digit)=2)
    same => n,GotoIfTime(8:00-19:58,*,*,*?Accueil,start,1)
    same => n,Playback(silence/2&welcome)
    same => n,SayUnixTime(,Europe/Paris,AdBY kM)
    same => n,Playback(what-time-it-is&what-time-it-is2)
    same => n,Playback(vm-goodbye)
    same => n,Hangup()

    same => n(pstn-dial),GoSub(subDialer,start,1(SIP/sip-dect,30))
    same => n,Set(MY_DIAL_STATUS=${GOSUB_RETVAL})
    same => n,GotoIf($["${GOSUB_RETVAL}" = "ANSWER"]?torture,s,1)
    same => n(pstn-vm),GoSub(subVoicemail,start,1(666,default,${MY_DIAL_STATUS}))
    same => n,Hangup()
    same => n(masqued_call),PlayBack((silence/2&privacy-unident&silence/2)
    same => n,Hangup()
    same => n(blacklisted),PlayBack(silence/2&tt-allbusy&silence/2)
    same => n,Hangup()

[From-Linphone]
    exten => s,1,Goto(From-Ovh,s,1)

[From-Ovh]
exten => s,1,Set(DIAL_OPTS=gtmx)
    same => n,GoSub(subDialVm,start,1(SIP/sip-dect,610)) 

[unauthenticated]
exten => s,1,NoOp("Unauthenticated")
    same => n,Hangup()

Le programme telnumck

Le programme telnumck, mentionné au paragraphe précédent, a maintenant sa propre page que vous pouvez consulter ici programme telnumck.

Le programme produit sur la sortie standart une réponse Wok si le numéro est dans le fichier TelWhite, une réponse Bok si le numéro est dans le fichier TelBlack et une réponse ko si numéro n'a pas été trouvé. C'est cette réponse qu'Asterisk analyse pour prendre ses décisions.

Messagerie vocale

Lorsqu'un appel n'a pas reçu de réponse, il est redirigé vers la messagerie vocale. Celle ci est configurée dans le fichier voicemail.conf. On y trouve une entrée pour chaque utilisateur local dans le contexte default

;
; voicemail.conf - Voicemail Configuration
;

[general]
format = wav|wav49
serveremail = asterisk@pi         ; Who the e-mail notification should appear to come from
attach = no                       ; Should the email contain the voicemail as an attachment
skipms = 3000                     ; How many milliseconds to skip forward/back when rew/ff in message playback
maxsilence = 10                   ; How many seconds of silence before we end the recording
silencethreshold = 128            ; Silence threshold (what we consider silence
maxlogins = 3                     ; Max number of failed login attempts
emaildateformat = %A, %d %B %Y at %H:%M:%S
pagerdateformat = %A, %d %B %Y at %H:%M:%S
; Allow the user to compose and send a voicemail while inside VoiceMailMain()
sendvoicemail = no
mailcmd = /usr/bin/vmnotif
; mailcmd=/usr/sbin/sendmail -t
;externnotify = /usr/bin/vmnotif
pollmailboxes = yes
pollfreq = 60

[zonemessages]
eastern=America/New_York|'vm-received' Q 'digits/at' IMp
central=America/Chicago|'vm-received' Q 'digits/at' IMp
central24=America/Chicago|'vm-received' q 'digits/at' H N 'hours'
military=Zulu|'vm-received' q 'digits/at' H N 'hours' 'phonetic/z_p'
european=Europe/Paris|'vm-received' a d b 'digits/at' HM

[default]
601 => **601, H.Q, hq@olix
602 => **602, F.Q, fq@olix
603 => **603, M.Q.,mq@olix
610 => **610,ovh.,hq@olix
666 => **610,pstn.,hq@olix

La lecture des messages vocaux peut se faire en numérotant le 667. On y trouve un IVR encore plus compliqué que celui de torture. Aussi pour simplifier, les messages vocaux sont transformés en mp3 et envoyés par mail par la commande /usr/bin/vmnotif, que vous trouverez dans le répertoire contrib du paquet telnumck. Si la machine, fournissant le serveur mail, n'est pas en service, ce qui arrive quand je n'y suis pas, les messages sont stockés en local et la commande vmnotif est alors appelée par le cron et essayera régulièrement d'envoyer ces messages.

Fichier features.conf pour les transferts d'appel

Asterisk permet de faire des transferts d'appel, un transfert simple (blind transfer) ou un transfert assisté, qui sont configurés dans le fichier features.conf.

On va supposer que vous m'avez appelé sur mon Asterisk-PBX, et que nous sommes en communication. Mais comme je ne sais pas répondre à une de vos questions, je vais vous mettre en relation avec un troisième correspondant. Je numérote donc le numéro de ce correspondant précédé de ## et je raccroche, vous êtes en attente (avec ou sans la musique) et dès que le correspondant répond, vous êtes en communication avec lui. C'est un transfert simple.

Dans le cas du transfert assisté, nous sommes encore en communication, mais je précède le numéro du troisième correspondant par *2, je rentre en communication avec ce correspondant dès qu'il répond et vous êtes mis en relation avec lui dès que je raccroche.

Attention, les autorisations de transfert dépendent des flags T t donnés à la commande Dial dans extensions.conf.

;
; Sample Call Features (parking, transfer, etc) configuration
;

[general]
atxfernoanswertimeout = 30     ; Timeout for answer on attended transfer 
transferdigittimeout => 4 
featuredigittimeout = 3000     ; Max time (ms) between digits for feature activation
xfersound = beep
xferfailsound = beeperr 

parkext => 600                  ; What extension to dial to park.  Set per parking lot.
;parkext_exclusive=yes          ; Specify that the parkext created for this parking lot
                                ; will only access this parking lot. (default is no)
parkpos => 640-650              ; What extensions to park calls on. (defafult parking lot)
                                ; These need to be numeric, as Asterisk starts from the start position
                                ; and increments with one for the next parked call.
                                ; Set per parking lot.
context => parkedcalls          ; Which context parked calls are in (default parking lot)
                                ; Set per parking lot.
;parkinghints = no              ; Add hints priorities automatically for parking slots (default is no).
                                ; Set per parking lot.
parkingtime => 60               ; Number of seconds a call can be parked before returning.
                                ; Set per parking lot. (default is 45 seconds)


[featuremap]
blindxfer => ##   ; Blind Transfer
disconnect => 1   ; Disconnect Call
automixmon => *1  ; One Touch Record
atxfer => *2      ; Attended Xfer

[applicationmap]
apprecord => *1,caller,Macro,one-touch-record
testfeature => *9,peer,Playback,tt-monkeys  ;Allow both the caller and callee to play

Enregistrement des conversations

Il peut être utile d'enregistrer une conversation importante. Les commandes pour cela sont définies dans features.conf. Il s'agit de apprecord et automixmon. Donc si vous taper *1 en cours d'une conversation, elle est enregistrée dans un fichier wav qui est récupérable dans le répertoire /var/spool/asterisk/monitor. On peut, si on le désire, convertir le fichier en .mp3 en utilisant la commande lame. Pour arrêter, il suffit de retaper la même séquence de touches.

Attention, les autorisations d'enregistrer dépendent des flags X x donnés à la commande Dial dans extensions.conf.

Fichier cdr.conf

Ce fichier permet la configuration de l'enregistrement des appels dans un fichier de type csv. Il sert surtout à montrer l'acharnement de certains harceleurs !. Le fichier csv se trouve à l'emplacement /var/log/asterisk/cdr-csv/Master.csv.

;
; cdr.conf
;
[general]
enable = yes
unanswered = yes
;congestion = no
batch = no
;size=100
;time=300

[csv]
usegmtime = no     ; log date/time in GMT.  Default is "no"
loguniqueid = yes  ; log uniqueid.  Default is "no"
loguserfield = yes ; log user field.  Default is "no"
accountlogs = no   ; create separate log file for each account code. Default is "yes"

Voici une ligne du fichier log coupée en morceau pour tenir sur la page:

"","601","start","subDialer","""''Hervé''"" <601>","SIP/soft-sip-hq-00000049",
  "SIP/sip-dect-0000004a","Dial","SIP/sip-dect,30,tmX","2014-10-17 10:48:02",,
  "2014-10-17 10:48:09",7,0,"NO ANSWER","DOCUMENTATION","1413535682.73",""

Fichier modules.conf

Ce fichier permet de définir les modules qui ne sont pas nécessaires à la configuration et qui ne seront pas chargés.

; Asterisk configuration file
; The modules.conf file, used to define which modules Asterisk should load
; (or not load).
;

[modules]
autoload = yes

; Resource modules currently not needed
noload => res_speech.so
noload => res_phoneprov.so
noload => res_ael_share.so
noload => res_clialiases.so
noload => res_adsi.so

; PBX modules currently not needed
noload => pbx_ael.so
noload => pbx_dundi.so

; Channel modules currently not needed
noload => chan_oss.so
noload => chan_mgcp.so
noload => chan_skinny.so
noload => chan_phone.so
noload => chan_agent.so
noload => chan_alsa.so
noload => chan_unistim.so
; Application modules currently not needed
noload => app_nbscat.so
noload => app_amd.so
noload => app_minivm.so
noload => app_zapateller.so
noload => app_ices.so
noload => app_sendtext.so
noload => app_speech_utils.so
noload => app_mp3.so
noload => app_flash.so
noload => app_getcpeid.so
noload => app_setcallerid.so
noload => app_adsiprog.so
noload => app_forkcdr.so
noload => app_sms.so
noload => app_morsecode.so
noload => app_followme.so
noload => app_url.so
noload => app_alarmreceiver.so
noload => app_disa.so
noload => app_dahdiras.so
noload => app_senddtmf.so
; noload => app_sayunixtime.so
noload => app_test.so
noload => app_externalivr.so
noload => app_image.so
noload => app_dictate.so
noload => app_festival.so

noload => res_config_odbc.so
noload => res_config_ldap.so
noload => func_odbc.so
noload => res_odbc.so

Références

Download