REGISTRAR & PROXY SIP




Voici un autre projet qui a germé dans ma tête à force de m'intéresser à la ToIP et plus particulièrement au travers du protocole SIP (Session Initiation Protocol). Après avoir lu des documentations d'introduction au protocole, après avoir attaqué la RFC 3261 et autres, après avoir mis en place diverses configurations de téléphonie sur IP avec Asterisk, il était venu pour moi le moment de créer mon propre PABX-IP SIP.

Je n'ai pas utilisé de pile SIP existante ce qui fait que mon PABX-IP SIP est loin d'être complet et d'implémenter l'ensemble des fonctionnalités SIP éparpillées dans les nombreuses RFC. Il est amusant de s'apercevoir qu'il est cependant très simple de coder un proxy et un registrar SIP, en perl dans mon cas, alors que les solutions propriétaires du marché sont très onéreuses. Il y a encore de nombreuses entreprises qui, par méconnaissance de la technique, préfèrent acheter des solutions vendues par un commercial rassurant plutôt que de prendre une solution avec un "papier cadeau" moins joli mais toute aussi efficace.

Le logiciel que je propose ici est en plein développement, au gré des mes envies et de mes besoins. Si vous voulez que je prenne en compte vos besoins, vu que je ne suis pas encore devin, le mieux est de me le faire savoir (mon adresse email est en bas de page) !
Si vous voulez un outil très performant, désactivez la taxation, écrivez une discri et un LCR simples et courts, commentez tous les messages qui s'affichent dans la console (utile pour le debug ou pour suivre l'activité) car ils ralentissent le programme. Remplacez tous les die() par des warn() pour éviter qu'à la moindre erreur de socket (pas forcément liée au programme lui-même), le programme s'arrête.

En terme de code, le programme principal (pabx.pl) fait moins de 1000 lignes de codes pour la version 0.70. Le programme complet est en réalité plus conséquent (Fonctions, fichier de configuration, autres modules). Cependant les quelques autres fichiers sont également de taille réduite. Codé en perl, j'utilise les bibliothèques IO::Socket::INET (pour établir des sockets), Digest::MD5 'md5_hex' (pour le calcul des hash MD5 lors de l'authentification), Time::localtime (pour pouvoir dater les traces de taxation) Time::HiRes (pour gérer le temps avec une meilleure précision que la seconde), Class::Struct (pour gérer des structures de données) et threads ainsi que thread::shared (utilisation des threads et des variables partagées).

N'hésitez pas à me contacter pour toute demande d'aide dans l'installation, la configuration, ou encore sur la réutilisation de code (sous GPL v3). Vous trouverez mon adresse email en bas de page.

Si vous voulez proposer du code ou des corrections, je serai ravi de les intégrer. Je peux également mettre en place des outils tels que CVS ou Subversion pour des personnes qui voudraient contribuer régulièrement. Avis aux amateurs !

Sommaire :

  1. Dernières infos
  2. Les étapes du projet :
  3. Screenshots :
  4. Comment se procurer ce programme ? :
  5. Installation et configuration :
  6. LCR et discrimination :
  7. Taxation :
  8. Fonctionnalité de téléphonie :
  9. Performances :
  10. Téléphones compatibles :
  11. Sous quelle licence se trouve ce programme ? Quel est son coût ? :
  12. Me contacter :

Dernières infos

13/06/2010
Version 0.66 (Proxy + Registrar)
    Factorisation de la modification et de la création des messages/réponses SIP. Cela aboutit à la création d'une bibliothèque permettant de réutiliser le code pour d'autres logiciels.
    Remplacement des doubles guillemets entourants les chaînes de caractères par des simples guillements lorsqu'il n'y a pas d'interprétation à faire. Cela permettra de gagner un peu de vitesse.
    Diverses résolutions de bugs (sur l'authentification, sur les messages 6xx, ...).
    Mise-à-jour de la rubrique "Téléphones compatibles" : ajout de CSIPSimple. C'est un client SIP disponible sous Androïd, par exemple sur l'Archos 5IT. L'écriture particulière (non recommandée mais tolérée par la RFC 3261) des en-têtes To:, From: et Content-Length: a nécessité d'adapter le proxy SIP.
    Mise-à-jour de la page web.

10/05/2010
    Mise à jour de la page web.

08/05/2010
Version 0.60 (Proxy + Registrar)
    Le fichier de configuration a légèrement évolué ce qui rend les anciens fichiers de configuration incompatibles (des [] sont à remplacer par des {}).
    Insertion dans le code des indications sur les RFC utilisées (et plus précisément quels paragraphes).
    Plusieurs fonctions crées pour simplifier le code principal (logique programmation objet même si ce n'est pas encore du perl objet).
    Support de l'envoi de fréquences vocales (par message INFO).
    Correction d'un bug sur les numéros de téléphones trop longs qui faisaient planter le proxy SIP.
    Correction d'un bug sur la gestion des tempos et des retransmissions de trames, surtout lors d'un appel vers un numéro inexistant.
    L'authentification avec le proxy SIP utilise maintenant Proxy-Authenticate/Proxy-Authorization et non plus WWW-Authenticate/Authorization (cf RFC 3261, §22.2 et §22.3).
    Dans le fichier de taxation, les tentatives de communication (avec ensuite un échec ou une réussite) sont tracées. Cela permet de tracer les appels en absences et les appels vers des numéros interdit (et bloqués).
    La discrimination peut toujours se faire par rapport aux numéros appellant et appellé, mais on peut rajouter une contrainte sur l'heure (cf explications dans le § "LCR et discrimination").
    Diverses résolutions de bugs.

Version 0.18 (Notificateur)
    Amélioration du code : mise-à-jour nommage des variables, initialisation des variables avant utilisation.
    Il n'est plus nécessaire d'indiquer et maintenir les adresses IP des postes téléphoniques dans le fichier MeVo. L'information est demandée au registrar (ou récupérée dans le fichier de configuration général). Ce changement de format rend incompatible ce module avec les anciens fichiers de configuration MeVo.

29/07/2009
Version 0.51 (Proxy + Registrar)
    Les messages de debug en console ont maintenant un en-tête [DEBUG].
    Beaucoup plus de messages disponibles pour le suivi du traitement (commenté par défaut pour beaucoup).
    Le fichier LCR_Discri.conf a changer de format pour être plus flexible.
    Basculement d'une partie du code gérant l'authentification dans pabxFct.pl.
    Basculement du code gérant la taxation dans pabxFct.pl.
    Maintenant toutes les requêtes SIP (selon la RFC 3261) doivent être authentifiées (407 Proxy Authorization Required) et plus seulement lors de l'enregistrement. Cela n'est vrai que pour les postes dont nous avons définis un mot de passe. Une erreur dans les piles SIP des téléphones GRANDSTREAM a été mise en évidence (cf Téléphones compatibles).
    Corrections et améliorations du code.
    Protection contre la possibilité d'injection de code en intégrant des variables ($MaVariable) dans les messages SIP. Cela aurait permis d'afficher la valeur des variables utilisées dans le programme ou faire planter le programme (à cause du "use strict") en demandant la valeur d'une variable non déclarée.

26/04/2009
Version 0.45 (Proxy + Registrar)
    Correction sur la gestion du temps. On ne fait plus des cycles de 1s mais de 500ms => meilleure gestion des retransmissions.
    Nouvelle convention plus stricte de nommage des variables => renommage de la plupart des variables de pabxFct.pl.

24/04/2009
Version 0.44 (Proxy + Registrar)
    Toutes les fonctions, mêmes celles utilisant les threads, sont maintenant dans le fichier pabxFct.pl.
    Dans pabxFct.pl, renommage et contrôle de la portée des variables avec limitation de leur portée lorsque nécessaire.
    Implémentation de la fonctionnalité "groupement de poste" avec le cas de l'appel de tous les postes en même temps (fonctionnalité aussi appellée single line extension).
    Suppression de codes morts.
    Mise-à-jour de la page web pour prendre en compte les nouvelles fonctionnalités proposées par le proxy SIP.
    Utilisation de "use strict ;" dans le programme principal, obligeant à écrire un code plus propre => plus de 800 warnings corrigés !
    Revue du thread gérant la tempo et le suivi des communications. Si le poste appelé sonne mais ne répond pas au bout de 60 secondes, on arrête de suivre l'invitation d'appel sans envoyer de 480 à l'appellant. S'il décroche après 60 secondes (c'est-à-dire que le poste de l'appellé n'ait pas envoyé de message de non-réponse et que l'appellant a attendu patiemment jusque là), alors la communication peut tout de même être établie.
   
30/11/2008
Mise à jour de la page web.

30/09/2008
Version 0.39 (Proxy + Registrar)
    Fin de l'intégration dans le code de la fonctionnalité LCR.

29/09/2008
Mise à jour de la page web (documentation de la taxation, de la discri et du LCR).
Version 0.38 (Proxy + Registrar)
    Gestion du paramètre received= pour pouvoir fonctionner avec des UAC dans un environnement "NATé".
    Mise en oeuvre de la discrimination (n'importe qui ne peut pas appeller n'importe quel numéro). Voir les explication de sa programmation sur cette page.
    Début de la mise en oeuvre du LCR (Less Cost Routing). Voir les explications de sa programmation sur cette page.
    Pour la taxation, un message est généré à l'établissement et à la clôture de la communication. Cela est stocké dans le fichier Taxation.txt. Voir les explications sur cette page.
    Corrections et améliorations diverses du code (meilleur suivi des branch=, gestion améliorée des sockets, ...).

22/07/2008
Version 0.33 (Proxy + Registrar)
    Amélioration de la gestion des tempos et retransmissions.
    Correction de bugs dans la composition des messages SIP.
    Le proxy SIP répond un 480 No Response à l'appellant si pas de réponse de l'appellé (terminal déconnecté).
Version 0.9 (Clic To Dial)
    Il est maintenant possible de lancer jusqu'à 100 instances en parallèle.
    Amélioration du code.

12/07/2008
Mise à jour de la page web.
Version 0.31 (Proxy + Registrar)
    Corrections de bugs et optimisations habituelles (fin de la chasse aux fuites mémoires).
    Protection contre les boucles (cas d'un poste s'appellant lui-même) avec message d'alerte.
    Gestion de la réponse 481.
    Message d'alerte si un message SIP n'est pas reconnu.
    Rechargement du programme "au bon moment" : en créant un fichier reload (vide) dans le même répertoire, le programme se terminera et se relancera automatiquement (pour, par exemple, relire le fichier de configuration) seulement une fois la dernière communication terminée afin d'éviter des coupures d'utilisateurs.
    Nouveau benchmark : dans les cas les plus pessimistes, la version 0.31 peut gérer 4 fois plus (> 100) de communications que la version 0.27 !

07/07/2008
Mise à jour de la page web. Tous les programmes sont sous GPL v3.
Version 0.29 (Proxy + Registrar)
    Corrections de bugs, améliorations, optimisations diverses dans le code :
  1. concernant les variables : passage par référence pour les résultats des fonctions, initialisation, gestion de la visibilité, pour plus de stabilité ;
  2. concernant l'agencement du code pour gain de traitement : le traitement des méthodes et réponses les souvent utilisées (REGISTER, INVITE, BYE, ...) est accessible plus rapidement. Par ordre décroissant d'utilisation on retrouve les autres méthodes ou réponses.
  3. remaniement complet des fonctions et faire en sorte que ça marche enfin (réintégration de certaines fonctions dans le fichier pabx.pl, optimisation, corrections de bugs, ...)
  4. chasse aux fuites mémoires.
  5. passage du contrôle de la tempo toutes les secondes et non 0.5s ==> machine interrompue moins souvent.
Version 0.8 (Clic To Dial)
    Améliorations de la gestion de l'établissement de l'appel. Cela reste encore rudimentaire.
Version 0.17 (Notificateur)
    Quelques améliorations.

08/06/2008
Mise à jour de la page web.
Version 0.27 (Proxy + Registrar)
    Beaucoup de modifications dans le code pour permettre un fonctionnement par thread ! Un thread tourne en parallèle au programme principal pour gérer les tempos et générer des retransmissions si nécessaire. Précision des tempos de l'ordre de 500 ms.
    Le découpage de l'en-tête et les autres fonctions ont été mises dans un fichier à part.
    Modification de la feuille de route : concentration sur les fonctionnalités de Proxy SIP et de Registrar. Abandon pour le moment de l'implémentation d'un fork server.
    Modification du fichier de configuration (config.pl) en conséquence.
Version 0.7 (Clic To Dial)
    Réutilisation du fichier des fonctions au lieu de les réimplémenter.
Version 0.15 (Notificateur)
    Réutilisation du fichier des fonctions au lieu de les réimplémenter.

31/05/2008
Mise-à-jour de la page web.
Création d'un fichier de configuration utilisable par tous les modules. Il n'est plus nécessaire d'aller dans les codes sources pour la configuration générale.
Version 0.25 (Proxy + Registrar)
    Prise en compte du fichier de configuration.
    Mise-à-jour de préfixes pour préparer la prise en compte du single line extension.
    Rajout de code (pour le moment sans effet) pour prendre en compte le temps (tempo d'attente des réponses, ...). Ceci afin de préparer l'arrivée des prochaines fonctionnalités.
    Diverses modifications et corrections dans le code.
Version 0.6 (Clic To Dial)
    Prise en compte du fichier de configuration
Version 0.14 (Notificateur)
    Rien de neuf.

08/04/2008 :March 14, 2008
Mise-à-jour de la page web.
Version 0.22 (Proxy + Registrar)
    L'authentification (basée sur la RFC 2617) est maintenant gérée (qop="auth" uniquement).
    Gestion du "480 Unavailable".
    Correction de divers bugs et optimisation du code (pour rester en-dessous des 1000 lignes = 970 lignes de codes !).
Version 0.5 (Clic To Dial)
    Améliorations et corrections diverses du code.
Version 0.13 (Notificateur)
    Rien de neuf.

21/01/2008 :
Version 0.19 (Proxy + Registrar)
    Rien de neuf.
Version 0.4 (Clic To Dial)
    Première publication.
Version 0.13 (Notificateur)
    Quelques corrections de bugs communs avec pabx.pl.

19/01/2008 :
Version 0.19Version 0.7 (Clic To Dial)
    Réutilisation du fichier des fonctions au lieu de les réimplémenter.
    De très nombreuses modifications, corrections de bugs et de nombreux ajouts de fonctionnalités ou de paramètres d'en-tête. Ekiga fonctionne sans problème maintenant aussi bien pour la partie Registrar que pour la partie Proxy. Améliorations également des regexps.

16/01/2008 :
Version 0.18
    Seconde publication. Ca avance, quelques bugs résolus, testé avec d'autres téléphones que des GrandStreams, des tests de performances et des améliorations en conséquence, ...

22/12/2007 :
Version 0.12 :
    Qu'est-ce que cette étrangeté ? C'est loin d'être le premiet jet, mais c'est la première publication sur le net.

Les étapes du projet :

         Étape 0 : Développement non commencé = Pas de nouveau besoin pour le moment. Projet arrêté (pas nécessairement définitivement).
         Étape 1 : Développement commencé = De nouveaux besoins exprimés. Début du développement d'une nouvelle version.
==> Étape 2 : Développement en cours = Implémentation des fonctionnalités. Attente de nouveaux besoins et implémentation de ceux-ci. <==
         Étape 3 : Phase de tests = Toutes les fonctionnalités recherchées sont implémentées et plus de nouveaux besoins exprimés depuis plusieurs jours. Tests en environnement de production.
         Étape 4 : Publication = Logiciel stable et documenté, prêt à être mis en production.

Screenshots :

Tout est en console, mais voici à quoi ressemble les enregistrements des postes 200 et 210, puis une communication (invitation, sonnerie, décrochage, fin) du 210 vers le 200 :



Ci-dessous, l'initialisation de la notification (0 messages pour les postes 200 et 210) sur les 2 premières lignes. Puis le 210 a un message (3ième ligne). Puis le 200 a 2 messages alors que le 210 n'en a plus (4ième et 5ième ligne). Au bout de 10 secondes, rappel au poste 200 qu'il a 2 messages en attente (6ième ligne). Puis le poste 200 les consulte et les efface car il n'y a plus de message en attente (dernière ligne).





Comment se procurer ce programme ? :

L'ensemble des fichiers se trouvent dans l'archive suivante : IPPBX.tar.gz.
Un fichier de configuration est utilisé par le programme principal et les modules. Il est fournit dans l'archive et s'appelle config.pl.

Le paquet ci-dessus ne contient pas les modules supplémentaires suivants :
--> Programme qui envoi un NOTIFY aux postes qui ont reçu un message vocal. Les postes qui supportent cette fonctionnalitée voient alors la LED messagerie clignoter ou s'allumer. Une fois le message consulté, ce programme renvoi un autre NOTIFY pour indiquer d'arrêter la signalisation (clignotemment LED) nouveau message sur le poste téléphonique. Le programme ne gère pas de messagerie vocale. Il lit les infos (nouveau message, message consulté, nombre de messages urgents, ...) que lui enverrait une messagerie vocale au travers d'un fichier texte. Le programme est disponible ici et l'exemple de fichier qu'il consulte ici.
--> Un Clic To Dial sera disponible ici (en cours de développement). Il faut que le Proxy SIP fonctionne en même temps (sur la même machine ou pas). On tape :
./pabxCTD.pl -s 500 -d 800
 
où 500 est le numéro du poste appellant et 800 celui de l'appellé. Le 500 sonne et  dès que l'on décroche, ça réalise un transfert d'appel vers le 800. Le 800 sonne et il ne reste plus qu'à décrocher pour être en relation avec le 500.
Les numéros de téléphones et les adresses IP correspondantes doivent être déclarés en dur dans le fichier pabxCTD.pl.

Installation et configuration :

--> Décompresser IPPBX.tar.gz et mettre les modules supplémentaires dans un même dans un même répertoire. Les fichiers de configuration doivent également être dans ce même répertoire.

--> Donner les droits d'exécution à tous les fichiers .pl sauf à config.pl (commande chmod 550 <nom du fichier>).


--> Renseigner le fichier de configuration config.pl :
    
Si l'on veut mettre des associations poste téléphonique <--> numéro de téléphone en statique, il faut le renseigner (rubrique "Numéros enregistrés en dur"). Par exemple, pour le numéro 200 ayant pour adresse 192.168.0.180 nous aurons :
$TabAdresse{"200"} = "192.168.0.180" ;

    Si le poste téléphonique maintient périodiquement son enregistrement (ou veut le supprimer), il doit s'authentifier (challenge MD5 pour éviter une usurpation). Le mot de passe du téléphone doit donc également être enregistré dans la configuration du PABX de la façon suivante (tatayet est le mot de passe du poste 200) :
$TabUA{"200"}[1] = "tatayet" ;

    Si les terminaux SIP sont capables de s'enregistrer, il n'est pas utile de déclarer l'adresse IP correspondant au poste, mais son mot de passe oui.
Un terminal SIP qui s'enregistre avec succès écrasera l'enregistrement que nous aurons défini pour lui dans le fichier.
   

    Nous pouvons également y indiquer le temps d'attente au bout duquel nous considérons l'appel comm échoué. Cette valeur est un nombre de cycle. Un cycle dure 0.5s. Toujours pour le poste 200, nous prenons, dans l'exemple ci-dessous, 30 secondes d'attente soit 60 cycles. Cette temporisation n'est utilisée que si le poste appellé sonne (renvoi d'un 180 RINGING) et qu'il ne répond pas ensuite aux réémissions. S'il ne répond pas du tout dès le début (téléphone éteint ou débranché du réseau) alors nous faisons différentes réémissions avec un temps maximum de 14 secondes.
$TabUA["200"][3] = 60 ; <== Ceci n'est plus utilisé à partir de la version 0.44
    Il y a d'autres paramètres à indiquer dans ce fichier de configuration comme le port et l'adresse du proxy SIP. Tout cela est commenté dans le fichier.

    Voici un exemple de fichier config.pl (les commentaires inutiles sont supprimés) :
[...]
# Nous enregistrons les numéros de postes 100, 200, 210, 220, 400 avec respectivement les adresses IP 192.168.1.100, 192.168.1.200, 192.168.1.210, 192.168.1.44, 192.168.1.60.
$TabAdresse{"100"} = "192.168.1.100" ;
$TabAdresse{"200"} = "192.168.1.200" ;
$TabAdresse{"210"} = "192.168.1.210" ;
$TabAdresse{"220"} = "192.168.1.44" ;
$TabAdresse{"400"} = "192.168.1.60" ;
[...]
# Paramètres UA
# Tous les postes ont ici le mot de passe tatayet, sauf le poste 400 qui n'est pas déclaré. Ce dernier ne pourra pas s'identitfier pour changer l'adresse IP qui lui est associée !
#
Le poste 220 est déclaré plus bas dans le fichier de configuration.
# Seul le poste 210 fait parti d'un groupement de poste (ou plutôt qu'il est un point d'entrée actif du groupement de postes).
$TabUA{"100"}[1] = "tatayet" ;
$TabUA{"100"}[5] = 0 ;
$TabUA{"200"}[1] = "tatayet" ;
$TabUA{"200"}[5] = 0 ;
$TabUA{"210"}[1] = "tatayet" ;
$TabUA{"210"}[5] = 1 ;
# Définition d'un groupement de postes (ici lorsque le 210 est appellé). On voit les adresses IP des postes ou proxy SIP qui seront sollicités.
$TabUAFork{"210"}[10] = "192.168.1.1:5060" ;
$TabUAFork{"210"}[11] = "192.168.1.11:5060" ;
$TabUAFork{"210"}[12] = "192.168.1.200:5060" ;
$TabUAFork{"210"}[13] = "192.168.1.13:5060" ;
$TabUAFork{"210"}[15] = "192.168.1.15:5060" ;
$TabUAFork{"210"}[17] = "192.168.1.17:5060" ;
# Il n 'est pas nécessaire de faire suivre les déclarations, même si cela apporte une meilleure visibilité. On voit ici le poste 220 dont on déclare
#le mot de passe (toto) et qu'il n'est pas le point d'entrée d'un groupement de postes.
$TabUA{"220"}[1] = "toto" ;
$TabUA{"220"}[5] = 0 ;
############################
#############################
# Déclaration des constantes
$PORT = 5060 ; # Port de connexion au serveur
$NAME = "PABX_IP" ; # Nom du serveur
$ADRESSESRV = "192.168.1.44" ; # Adresse IP du serveur
$ADRESSEGW = "91.121.129.17" ; # Adresse IP du serveur auquel on envoie les requêtes quand on ne connait pas le destinataire.
$PORTGW = 5060 ;
$DOMAINE = "maison.com" ; # Domaine.
$CHAINETAGBRANCH = "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN0123456789" ; # Caractères utilisables pour créer un tag ou une branch.
$NUMCTD = "0979122222" ; # Numéro avec lequel le Clic-To-Dial s'identifie.
$SECRETCTD = "xknhtttt" ; # Mot de passe servant à l'authentification du Clic-To-Dial.
#############################
###########################
# Déclaration des préfixes.
## Un préfixe commence par étoile (*) suivi du nombre indiqué ci-dessous.
$NOADDNUM = 10 ; # Ce préfixe est pour annuler un numéro supplémentaire sur le poste
$ADDNUM = 11 ; # Ce préfixe est pour déclarer un numéro supplémentaire sur le poste
$NORENVINC = 20 ; # Ce préfixe est pour annuler un renvoi inconditionnel vers un autre poste depuis le proxy
$RENVINC = 21 ; # Ce préfixe est pour faire un renvoi inconditionnel vers un autre poste depuis le proxy
###########################

--> Configurer la discrimination et le LCR dans le fichier LCR_Discri.conf. Pour plus de détails, voir plus bas dans cette page.

--> Charger en mémoire pabx.pl et pabxNOT.pl (optionnel) et c'est terminé !



--> Pour utiliser le Clic To Dial, il suffit de taper :
./pabxCTD.pl -s <Numéro appellant> -d <Numéro appellé>
Si nous voulons lancer plusieurs appels en même temps, faire de même dans plusieurs fenêtres shells ou
./pabxCTD.pl -s <Numéro appellant 1> -d <Numéro appellé 2> & ./pabxCTD.pl -s <Numéro appellant 3> -d <Numéro appellé 4> & ...

LCR et discrimination :

Le LCR (Less Cost Routing, routage vers le chemin le moins onéreux) est initialement la fonctionnalité permettant de sélectionner la meilleure passerelle, d'un point de vue coût de communication, pour atteindre le numéro appellé. Il est possible d'utiliser ce routage d'appel pour des raisons qui n'ont rien à voir avec les coûts : les appels entrants en journée peuvent être redirigés vers un répondeur commun à partir d'une certaine heure le soir, ainsi que le samedi et le dimanche.
La discrimination est l'ensemble des autorisations concernant les appels. On y définit donc si tel poste a le droit d'appeller sur des portables, sur des fixes, des numéros à l'international, des numéros sur-taxés, ...

Tout cela se configure dans le fichier LCR_Discri.conf avec une syntaxe particulière basée sur des expressions régulières. Il est possible de mettre des commentaires en commençant par (entre autres) #. Toute la ligne est commentée. La syntaxe des règles est la suivante :
<expresssion rationnelle numéro appellant> --> <expression rationnelle numéro appellé>  <option1:valeur> <option2:valeur> <...>

Voici les options possibles :
Decision : suit un des choix suivant INTERDIT ou AUTORISE ou LOCAL.
    INTERDIT : communication interdite.
    AUTORISE : communication autorisée vers un numéro qui n'est pas enregistré dans le PABX et la passerelle de sortie (ou tout périphérique SIP tel qu'un autre téléphone) est indiquée en suivant.
    LOCAL : le poste appellé est enregistré sur le PABX-IP et il est donc accessible directement, sans passer par un autre Proxy SIP. Les appels répondant à LOCAL sont toujours autorisés.
Time : suit la définition du créneau horaire pendant lequel cette règle de routage est active. Le format est le suivant HH:mm-HH:mm;Js-Js;Jm-Jm;MM-MM avec :
    HH:mm-HH:mm définit le créneau Heure:minute.
    Js-Js définit les jours de la semaine compris dans le créneau (0=dimanche, ..., 6=samedi).
    Jm-Jm définit les jours dans le mois compris dans le créneau (1=janvier, ..., 12=décembre).
    MM-MM : définit les mois dans l'année compris dans le créneau.
    Exemple : règle active de 15h10 à 16h20 du lundi au vendredi, les 15 premiers jours des 6 derniers mois de l'année : Decision:15:10-16:20;1-5;1-15;7-12
   
On ne peut pas faire de définition fragmentée du style "règle active de 8h à 12h puis de 14h à 18h". Il faut passer par la rédaction de plusieurs règles (une pour le matin et une autre pour l'après-midi).
Next : suit l'adresse IP vers laquelle envoyer l'appel si celui-ci a été préalablement autorisé. Il faut que Decision soit à AUTORISE.


Illustrons par des exemples :
La numérotation interne de l'entreprise est sur 4 chiffres.
Tous les postes peuvent être appellés du lundi au vendredi de 8h30 à 20h, et cela tout au long de l'année. Le reste du temps (le soir et la nuit), les appels entrants sont bloqués).
Je veux autoriser tous les postes à appeller les fixes en France. La passerelle à contacter est alors 163.125.2.1.
Seuls les postes de l'équipe direction, dont le numéro est compris entre 4000 et 4999 (donc commençant par 4) sont autorisés à appeller les portables en passant par la même passerelle que pour les appels vers les téléphones fixes.
Seuls les postes 4400 et 4521 sont autorisés à appeller des numéros en 08. La passerelle est alors le 125.12.1.11 en journée et en semaine. Le soir, la nuit et tout le week-end, ils emprunteront la passerelle 163.125.2.1.
Ne pas oublier à la fin la règle par défaut : tout interdire.

\d{4} --> \d{4} Decision:LOCAL
.* --> \d{4} Decision:LOCAL Time:08:30-20:00;1-5;1-31;1-12
\d{4} --> 0[1-5]\d{8} Decision:AUTORISE  Next:163.125.2.1
4\d{3} --> 06\d{8} Decision:AUTORISE Next:163.125.2.1
[4400,4521] --> 08\d{8} Decision:AUTORISE Next:125.12.1.11 Time:08:30-20:00;1-5;1-31;1-12
[4400,4521] --> 08\d{8} Decision:AUTORISE Next:163.125.2.1 Time:20:01-23:59;1-5;1-31;1-12
[4400,4521] --> 08\d{8} Decision:AUTORISE Next:163.125.2.1 Time:00:00-08:29;1-5;1-31;1-12
[4400,4521] --> 08\d{8} Decision:AUTORISE Next:125.12.1.11 Time:00:00-23:59;0-6;1-31;1-12
.* --> .* Decision:INTERDIT

Le service des ressources humaines (100 à 199) doit pouvoir appeller le service de comptabilité (200 à 299) ainsi que le service technique (300 à 399). Ces 2 derniers ne doivent pas pouvoir se joindre, mais ils peuvent appeller les services des RH (et oui, pensez à autoriser les appels dans les deux sens !). Ces trois services s'enregistrent sur notre proxy/registrar SIP. Pas d'appel vers l'extérieur. Pas de contrainte horaire.

1\d{2} --> 2\d{2} Decision:LOCAL
1\d{2} --> 3\d{2} Decision:LOCAL
2\d{2} --> 1\d{2} Decision:LOCAL
3\d{2} --> 1\d{2} Decision:LOCAL
# Règle par défaut : tous les appels non-définis ci-dessus sont interdits, même s'ils sont locaux.
.* --> .* Decision:INTERDIT

Ces exemples sont donnés pour aider à la compréhension et sont bien trop simplistes pour une utilisation en environnement réel. Il faudrait interdire les 3615, 3003 et autres services de France Télécom. Les numéros gratuits et d'urgence devraient être autorisés, nous devrions définir un préfixe pour mieux identifier les appels vers extérieurs, ect.

Taxation :

La taxation consiste à tracer les tentatives d'appels, l'établissement (réussi) des appels et leur clôture. Cela est stocké dans le fichier Taxation.txt sous le format suivant :
[TAX] jour/mois/année heure:minute:seconde  <Comm début|Comm fin|Tentative>  ChampFrom --> ChampTo

Exemple :
Le poste 200 appelle le poste 400 qui décroche au bout de 3 secondes. La communication se terminera 5 secondes plus tard.
Le poste 210 appelle le poste 300 qui décroche au bout d'une seconde et reste en ligne que 7 secondes.
Le poste 200 appelle le poste 300 qui ne décroche pas.
Le poste 400 appelle le poste 200 qui décroche au bout de 7 seconces et ne reste en ligne que 2 secondes.

[TAX] 27/3/2010 14:16.38 Tentative 200@192.168.1.44 --> 400@192.168.1.44
[TAX] 27/3/2010 14:16.41 Comm_début 200@192.168.1.44 --> 400@192.168.1.44
[TAX] 27/3/2010 14:16.42 Tentative 210@192.168.1.44 --> 300@192.168.1.44
[TAX] 27/3/2010 14:16.43 Comm_début 210@192.168.1.44 --> 300@192.168.1.44
[TAX] 27/3/2010 14:16.46 Comm_fin 200@192.168.1.44 --> 400@192.168.1.44
[TAX] 27/3/2010 14:16.50 Comm_fin 210@192.168.1.44 --> 300@192.168.1.44
[TAX] 27/3/2010 14:16.53 Tentative 200@192.168.1.44 --> 300@192.168.1.44
[TAX] 27/3/2010 14:17.27 Tentative 400@maison --> 200@maison;user=phone
[TAX] 27/3/2010 14:17.34 Comm_début 400@maison --> 200@maison;user=phone
[TAX] 27/3/2010 14:17.36 Comm_fin 200@maison;user=phone --> 400@maison

Il ne reste plus qu'à retraiter le fichier avec le tableur ou le script de son choix pour ventiller les coûts aux différents centres de taxation.

Il est possible de supprimer la taxation pour obtenir de meilleures performances (impact à l'établissement et à la clôture des communications, mais impact faible) en commentant, dans le fichier pabx.pl, les lignes suivantes commençant par &Taxation.

Fonctionnalité de téléphonie :

Enregistrement :
Enregistrement
des terminaux téléphoniques, qu'ils soient logiciels ou matériels.
L'authentification par mot de passe est prise en charge et est obligatoire.

Communication et renvois :
Etablissement de la communication
entre 2 UA suite à la demande de l'un d'eux.
Gestion des transferts sur non réponse inités par l'appellé.
Gestion des transferts sur occupation initiés par l'appellé.
Gestion des transferts inconditionnels inités par l'appellé.
Gestion des transferts inconditionnels inités par le proxy SIP (suite à l'utilisation antérieure d'un préfixe par l'appellé pour activer et configurer cette fonctionnalité).

Clôture et rejets :
Gestion de la clôture de la communication entre 2 UA.
Gestion du renvoi de l'état "indisponible" à l'appellé (480 Unavailable).
Gestion du renvoi de l'état "occupé" à l'appellé (486 Busy).
Gestion de la clôture de la demande de communication par l'appellant avant que l'appellé ait décroché (487 Request Canceled).
Gestion du fait de décliner une invitation (réponse d'un 603 Decline à un INVITE).

Groupement de poste :
Appel simultané de plusieurs postes lorsqu'un numéro est composé (par exemple un des poste du groupement). Appellé aussi fonctionnalité single line extension. Les postes renvoyant un message 48x (occupés, non-réponse, ...) sont pris en compte. Le premier poste qui répond récupère la communication. La sollicitation des autres postes du groupement s'arrête alors immédiatement.

Discrimination (voir le paragraphe détaillé plus haut) :
Filtrage des appels émis.
Filtrage des appels reçus.

LCR
(voir le paragraphe détaillé plus haut) :
Routage des appels en fonction du numéro appellé.
Routage des appels en fonction du numéro appellant.
Routage des appels en fonction de l'heure d'appel.

Divers :
Déclaration de numéros supplémentaires sur un poste (suite à l'utilisation d'un préfixe par l'appellé pour activer et configurer cette fonctionnalité).
Gestion de la souscription d'un poste à des services (comme notification d'arrivée de nouveaux messages vocaux). Partiellement implémenté.
Coupure micro demandée par les UA.
Mise en attente de la communication demandée par un UA.
Double appel.
Redémarrage du Proxy SIP dès que la dernière communication est libérée : pour activer le redémarrage, ajouter un fichier nommé reload dans le même répertoire que pabx.pl.

Autre types de serveurs (non implémenté ici) :
Find me : Cela peut-être vu comme un groupement de postes à appels cycliques avec une tête de liste fixe. Il est simple de reproduire cette fonctionnalité. Prenons la liste des téléphones à appeller dans l'ordre : A, B, C et D. Il suffit de configurer sur A le renvoi d'appel sur non-réponse vers B. Sur B la même chose avec le renvoi cette fois sur C. Sur C, renvoi sur D. On peut boucler en renvoyant D sur A, mais cela va au-delà de la fonctionnalité Single Line Extension.

Session via Redirect and Proxy Servers with SDP in ACK : REDIRECT SERVER.

Session with Multiple Proxy Authentication.

Récapitulatif des préfixes :
*10 : Suppression du rajout d'un numéro à un poste.
*11 : Déclaration d'un numéro supplémentaire à un poste. Plusieurs peuvent être rajoutés.
*20 : Suppression d'un renvoi inconditionnel du poste vers un autre. Ce renvoi était géré par le proxy SIP.
*21 : Déclaration d'un renvoi inconditionnel du poste vers un autre numéro. Ce renvoi est géré par le proxy SIP.
En projet :
*40 suivi du poste associé : Suppression d'un poste associé. Si l'on indique 0000, alors toutes les associations sont supprimées.
*41
suivi d'un chiffre de 0 à 9 : Déclaration d'un poste associé (10 maximum). Tous les postes associés sont sonnés en même temps lors d'un appel.

Performances :

(Avec peu de trafic)
Empreinte RAM : 6 Mo (hors utilisation mémoire que nous pourrions avoir en chargeant le programme dans une console), mais cela peut augmenter de quelques Mo si de nombreuses machines s'enregistrent.

CPU : insignifiant (<1%) sur un Céléron 2.4 GHz.
Espace disque : >150 Ko, hors fichier de configuration (contenant la déclaration des terminaux SIP), les logs (taxation, ...) et l'interpréteur perl.

Pour améliorer la réactivité du programme en cas de forte charge de la machine, il est conseillé d'augmenter la priorité d'exécution des processus liés au proxy SIP (diminuer la valeur à -1 ou -2 à l'aide de la commande nice).

Concernant le Proxy + Registrar en version 0.62 et selon des "benchmarks maisons" (un wireshark qui me permet de voir le délai entre la réception d'un message SIP, son traitement et le renvoi d'une réponse par le logiciel), nous pouvons gérer au minimum 250 établissements de communications par seconde. Etant donné qu'il faut qu'une demande de communication soit traitée dans les 14 secondes avant que le terminal téléphonique retourne une fin de non recevoir à l'utilisateur, le logiciel est donc prêt à encaisser un pic de 3500 communications simultanées suivi d'arrivées de 250 communications supplémentaires par secondes !
Le calcul est le suivant : nous mettons 0.002 secondes pour traiter une message entrant et le faire suivre ou pour envoyer une réponse. Pour traiter une demande de communication, à la réception de la primitive INVITE, nous répondons 180 Trying en 0.002s et faisons suivre l'INVITE modifié en 0.002s de plus.
Ce sont des tests sur un LAN et sont loin d'être incontestables. Rien ne vaut le test grandeur nature, mais mon benchmark à le mérite de donner un ordre d'idée.

Téléphones compatibles :

Jusqu'à la v0.45 :
GrandStream <--> GrandStream : OK.
GrandStream <--> Siemens 470IP : OK.
GrandStream <--> Ekiga : OK.

Ekiga <--> Siemens 470IP : NOK.


v0.50 et au-delà :
GrandStream : une erreur dans la pile SIP de ces téléphones nécessite de changer la ligne (env. 265ième ligne)
if (($StrctSIPHeader->HLigneEtat->{'Method'} eq 'ACK' && $TabSession[$NumComm] =~ /40[17]/) || $StrctSIPHeader->HLigneEtat->{'Method'} eq '' ) {
par
if (($StrctSIPHeader->HLigneEtat->{'Method'} !~ /(REGISTER|INVITE|BYE)/) || $StrctSIPHeader->HLigneEtat->{'Method'} eq '' ) {
car l'algorithme de calcul du hash final dans "WWW-Authenticate" ne correspond pas à celui des RFC 3261 & 3665 pour les ACK, CANCEL et BYE.


GrandStream
Siemens 470IP
CSIPSimple
Ekiga
XLite
GrandStream
OK
OK
OK
test à faire
test à faire
Simens 470IP
OK
matériel manquant*
OK
test à faire
test à faire
CSIPSImple
OK
OK
matériel manquant*
test à faire
test à faire
Ekiga
test à faire
test à faire
test à faire
matériel manquant*
matériel manquant*
XLite
test à faire
test à faire
test à faire
matériel manquant*
matériel manquant*
* : par manque de matériel, je ne pourrai pas effectuer ces tests.

Sous quelle licence se trouve ce programme ? Quel est son coût ? :

  Ce PABX-IP est gratuit, mais tout encouragement ou retour d'expérience est apprécié.
  Il est sous licence GPL version 3. Sauf contre rémunération convenue au préalable, je ne suis aucunement responsable de ce que vous pourriez en faire ou les problèmes que vous pourriez rencontrer suite à l'utilisation de ce logiciel.

Me contacter :

voir http://lehmann.free.fr, en bas de page