Programmation

Comment afficher le numéro de téléphone lors d’appels entre abonnés Sipgate et Asterisk (au lieu de l’identifiant interne Sipgate) ?

3 minutes de lecture

AstérisqueLes appels entre abonnés Sipgate sont automatiquement routés en tant qu’appels SIP, même si l’on appelle le numéro de téléphone « externe ». Cela présente l’avantage que les appels entre abonnés Sipgate sont gratuits, car les communications passent par Internet. Il serait toutefois appréciable de savoir qui m’appelle 😉

Problème :
Dans l’en-tête From ne figure pas le numéro de téléphone de l’appelant, mais l’URL SIP (par ex. <sip:12345e0@sipgate.de>). La variable CALLERID(num) définie par Asterisk ne contient alors plus que l’identifiant utilisateur SIP de Sipgate, comme par ex. 12345e0. La plupart du temps, les téléphones connectés à Asterisk ne peuvent rien en faire. Si l’identifiant contient une lettre (ici dans l’exemple « e »), certains téléphones plus anciens n’affichent aucun numéro. Il est particulièrement frustrant de manquer un appel et de ne plus pouvoir identifier qui a réellement appelé.

Solution :
En examinant les en-têtes SIP, on constate que l’information souhaitée est contenue dans l’élément d’en-tête « P-Asserted-Identity » :

INVITE sip:5000@10.0.0.33 SIP/2.0
...
From: <sip:12345e0@sipgate.de>;tag=CAFEBABE
To: <sip:072198765432@sipgate.de>
Contact: <sip:12345e0@12.34.56.78;uniq=CAFEAFFE23>
...
P-Asserted-Identity: <sip:072112345678@sipgate.de>

Le format peut varier chez d’autres fournisseurs. Pour en savoir plus, consultez http://www.ietf.org/rfc/rfc3325.txt.

À des fins de démonstration, j’ai écrit un petit plan de numérotation (dialplan) pour Asterisk :

; debug
exten => 5000,1,NoOp(Caller-ID: ${CALLERID(all)})
exten => 5000,2,NoOp(SIP From: ${SIP_HEADER(From)})
exten => 5000,3,NoOp(SIP To : ${SIP_HEADER(TO)})
exten => 5000,4,NoOp(SIP PAI : ${SIP_HEADER(P-Asserted-Identity)})

; try to extract phone number from sip header P-Asserted-Identity
exten => 5000,5,Set(FON=$["${SIP_HEADER(P-Asserted-Identity)}" : " 5000,6,ExecIf($[${ISNULL(${FON})}=0]?Set(CALLERID(num)=${FON}))

; debug
exten => 5000,7,NoOp(Caller-ID: ${CALLERID(all)})
...

Explication :
5 : Nous extrayons le numéro avec RegExp et enregistrons le résultat dans la variable FON.
6 : Si FON n’est pas nul, nous remplaçons CALLERID(num) par la valeur de FON.

Voici deux cas d’utilisation et la sortie d’Asterisk :
Abonnés pour l’exemple (les numéros de téléphone, les adresses IP ainsi que toutes les balises sont masqués).
Appelé (Asterisk avec compte Sipgate) :
– Numéro de téléphone = 072198765432
Appelant 1 (Fritzbox avec compte Sipgate) :
– Identifiant Sipgate = 12345e0
– Numéro de téléphone = 072112345678
Appelant 2 (Mobile) :
– Numéro de téléphone = 017112345678

Cas 1 : Appelant 1 (sipgate -> sipgate) :

-- Exec...1] NoOp("SIP/sipgate.de-000000b6", "Caller-ID: "" <12345e0>") in new stack
-- Exec...2] NoOp("S..b6", "SIP From: <sip:12345e0@sipgate.de>;tag=CAFEBABE") in new stack
-- Exec...3] NoOp("S..b6", "SIP To : <sip:072198765432@sipgate.de>") in new stack
-- Exec...4] NoOp("S..b6", "SIP PAI : <sip:072112345678@sipgate.de>") in new stack
-- Exec...5] Set("S..b6", "FON=072112345678") in new stack
-- Exec...6] ExecIf("S..b6", "1?Set(CALLERID(num)=072112345678)") in new stack
-- Exec...7] NoOp("S..b6", "Caller-ID: "" <072112345678>") in new stack
-- Exec...8] ...

Exec…5 : Le numéro de téléphone externe de l’appelant a été inscrit dans FON
Exec…6 : 1? => condition remplie => remplacer CALLERID(num)
Exec…7 : Vérification que le numéro a été remplacé (cf. Exec…1)

Cas 2 : Appelant 2 (mobile -> sipgate) :

-- Exec...1] NoOp("S..b8", "Caller-ID: "017112345678" <017112345678>") in new stack
-- Exec...2] NoOp("S..b8", "SIP From: "017112345678" <sip:017112345678@sipgate.de>;tag=cafebabe") in new stack
-- Exec...3] NoOp("S..b8", "SIP To : <sip:004972198765432@sipgate.de>") in new stack
-- Exec...4] NoOp("S..b8", "SIP PAI : ") in new stack
-- Exec...5] Set("S..b8", "FON=") in new stack
-- Exec...6] ExecIf("S..b8", "0?Set(CALLERID(num)=)") in new stack
-- Exec...7] NoOp("S..b8", "Caller-ID: "017112345678" <017112345678>") in new stack
-- Exec...8] ...

Exec…5 : La correspondance de motif (pattern matching) échoue car l’en-tête n’est pas défini, la variable FON est donc null.
Exec…6 : 0? => condition non remplie => ne rien faire
Exec…7 : Vérification que le numéro est resté inchangé (cf. Exec…1)

Les terminaux affichent désormais toujours le numéro de téléphone externe de l’appelant. Ainsi, l’appelant peut également être rappelé en cas d’appel manqué.

Bonne continuation,

= C. | Laboratoire technique SaaS Web =

P.-S. : Il est amusant de constater que l’application de Sipgate n’affiche elle aussi que l’identifiant interne (« Appel de 12345e0 »), ce qui prête à confusion sur l’identité réelle de l’appelant…