lundi 14 mars 2011

Comment reconnaitre en une seule requête SQL l'indicatif d'un numéro de téléphone

Mettons une table d'indicatifs:

Pays | Indicatif
-------------------
Pays0 | 2
Pays1 | 21
Pays2 | 212
Pays3 | 213
Pays4 | 3
Pays 5 | 321

Une table d'appels

IdAppel | NumCorrespondant
-------------------------------
1 | 276543
2 | 214525
3 | 213987
4 | 365145
5 | 321458

Est il possible en une seule requête, de trouver le pays selon l'indicatif, la difficulté ici est évidemment que l'indicatif n'est pas de longueur fixe, et sa longueur n'est pas limitée.

IdAppel | NumCorrespondant | Pays
---------------------------------------
1 | 276543 | Pays0
2 | 214525 | Pays1
3 | 213987 | Pays3
4 | 365145 | Pays4
5 | 321458 | Pays5


La solution elle est la !
L'astuce étant une sous requête qui sélectionne tous les pays pouvant correspondre a l'indicatif mais ne garde que le plus long, donc le plus correspondant!

SELECT IdAppel,NumCorrespondant,
(
SELECT Pays
FROM Indicatifs
WHERE Indicatif = LEFT(NumCorrespondant,length(Indicatif))
ORDER BY length(Indicatif) DESC
LIMIT 1
)
FROM Appels


en espérant que ca puisse être utile a quelqu'un, si quelqu'un en revanche connait mieux, je suis preneur.

jeudi 25 février 2010

mardi 1 décembre 2009

Ma rencontre avec DAHDI

Bonjour a tous.

Le contexte

Ça fait un bail que j'ai pas posté ici mais je tenais a vous faire partager ma surprenante rencontre avec DAHDI.
Étant malheureusement obligé de réinstaller Asterisk , encore plus malheureusement du passer a une version 1.4.
Au moment de récupérer les sources a compiler , oh surprise , notre bon vieux zaptel n'existe plus , il est remplacé par un bidule qui s'appelle dahdi.
Ce genre de surprises n'est en general pas désagréable a part quand on a 50 utilisateurs en arret de prod sur le dos, bref pas rigolo.
Après quelques recherches il s'avère que les changements avec zaptel sont pas si enormes qu'il n'y parait;

Les différences entre zaptel et dahdi - configuration

La compilation des dahdi,libpri,asterisk et asterisk-addons se déroule sans souci.

le zaptel.conf disparaît au profit du ,dahdi/system.conf dont la syntaxe s'avère être identique si ce n'est que les informations d'echo-cancellation sont a présent paramétrables par channel.
voici un exemple de configuration simple pour une carte TE110P reliée a un T2;

span=1,1,0,ccs,hdb3,crc4
bchan=1-15,17-31
dchan=16
echocanceller=mg2,1-15,17-31
# Global data
loadzone = fr
defaultzone = fr

Le zapata.conf disparait au profit du ,dahdi-channels.conf dans lequel je n'ais fait aucune modification.

Dans le extensions.conf le classique Dial(ZAP/g1... est simplement remplace par Dial(DAHDI/g1... (un simple remplacement de chaîne fait l'affaire).

Les différences entre zaptel et dahdi - outils

En ce qui concerne les différents outils existants pour la configuration et la supervision des channels et interfaces le classique ztcfg devient dahdi_cfg , zttest devient dahdi_test , zttool devient dahdi_tool.Plein d'autres utilitaires sont d'ailleurs disponibles avec dahdi.

Pour finir

En résumé, il n'y a vraiment pas de quoi paniquer devant dahdi, ca parait complètement différent mais avec un minimum de méthode la migration de zaptel a dahdi est très aisée.

bonne chance!

jeudi 31 juillet 2008

Un petit script de synchronisation de repertoires

Ma problématique était plus ou moins simple, permettre a deux serveurs de synchroniser certains répertoires entre eux (un serveur de production et un serveur de backup, le but étant de répercuter toutes les créations et modifications de fichiers sur le serveur de backup)
Donc en fait ce petit script quotidien est simple, il scanne les répertoires que l'on souhaite synchroniser, y détecte les modifications/créations ayant eu lieu dans la journée, crée une archive avec et un fichier de script a exécuter sur le serveur de backup ce qui répercute les modifications.Les transferts ont lieu par ftp:
Voici le code source;

modifs_du_jour.sh ; le script a exécuter tous les jours (dans le cron) sur le serveur de production:

#! /bin/sh
# SL 2008-07-21 Script de synchronisation des repertoires entre la prod et le backup
fichiermodifs=`date +%Y%m%d`'_modifs.sh'
fichiermodifsgz='modifsjour'`date +%Y%m%d`'.tar.gz'
#coordonnees ftp du serveur cible
serveurftp='XXXXXXXXXXX'
userftp='XXXX'
mdpftp='XXXX'
#effacement des modifs de la veille
rm -f -R /db/modifsjour/*
#boucle sur chacun des repertoires que l'on veut synchroniser
for chemin in "/usr/local/scripts/" "/usr/local/apache2/htdocs/" "/bin/*.sh" "/db/factures*" "/db/relancesPDF/" "/db/Archivage/" "/db/contentieux/" "/db/contentieux/" "/db/courriersPDF/" "/db/courriersPDF/" "/db/CR_SiegesPDF/" "/db/tickets/"
do
echo "Traitement de : "$chemin
#creation d'une ligne dans le script qui s'executera sur le serveur de backup avec tous les
#fichiers modifies dans la journee
find $chemin -name "*.*" -mtime 0 | awk 'BEGIN{FS="/"}{print "/bin/sh /bin/repcp.sh \"" $NF "\" \""$0"\""}' >> /db/modifsjour/$fichiermodifs
#copie dans un repertoire de tous les fichiers modifies dans la journee
find $chemin -name "*.*" -mtime 0 | awk '{print "cp \"" $0 "\" /db/modifsjour/"}'|sh
done
cd /db/
#creation de l'archive
tar -cvzf $fichiermodifsgz /db/modifsjour/
#transfert ftp vers le serveur de backup
/usr/bin/ftp -nv $serveurftp < <SCRIPT
quote USER $userftp
quote PASS $mdpftp
binary
prompt
cd modifs
mdelete *.gz
put $fichiermodifsgz
prompt
quit
SCRIPT
rm /db/$fichiermodifsgz

Il reste ensuite a exécuter sur le serveur de backup le script `date +%Y%m%d`'_modifs.sh' qui reconstitue les modifications a partir de l'archive 'modifsjour'`date +%Y%m%d`'.tar.gz'.
Il faut également le code source de repcp.sh qui est une copie récursive qui crée les répertoires si ils n'existent pas (très utile dans le cas de répertoires crées sur le serveur de production).

repcp.sh:

#! /bin/sh
cd /home/ilan/modifs/db/modifsjour/
source="$1"
target="$2"

if [ ! -d `dirname "$target"` ]
then
mkdir -m 755 -p $(dirname "$target")
fi
cp -Rfp "$source" "$target"
exit 0

en espérant vous avoir été utile et en implorant votre indulgence sur les scripts, c'est vraiment pas le langage que j'apprécie!

mercredi 23 juillet 2008

Asterisk 1.4 a bannir pour la production

Juste un petit billet pour largement vous encourager a rester sous Asterisk 1.2.x (et les zaptel libpri qui vont avec) et éviter le 1.4.
Ça fait trois ou quatre fois que j'essaie de passer mes serveurs de production sous 1.4.x (au fur et a mesure de la sortie des nouvelles versions stables) et a chaque fois une merde ; coupures,plantages bref la totale , tout disparaît des que je repasse en version 1.2.x.

jeudi 17 juillet 2008

Ma rencontre avec A2billing la plateforme de cartes prepayees et postpayees d'Asterisk

Le Contexte

Heureux administrateur d'une dizaine de serveurs Asterisk, je me suis vu confier un projet de gestion de comptes prépayés couplé avec notre IPBX Open Source favori.
La configuration étant simple
a priori , le client reçoit le numéro de téléphone du serveur, un code d'accès (ou reconnaissance de son numero appelant) et il peut composer et communiquer dans la limite du crédit lui restant.

La perte de temps idiote

Je me dit dans un premier temps que ça doit être faisable "maison" avec un petit script agi qui va taper dans une base de données pour identifier l'appelant (soit par un code tape soit par son CID) et qui lance la commande Dial qui va bien si il est authentifié (avec une limite de temps maximale correspondant a un calcul basé sur le coût de l'appel et son crédit restant).Une fois l'appel terminé une petite décrémentation de son crédit restant epicetou.
En fait j'y a ai pass
é deux jours et c'etait pas si trivial, je me suis meme carrément fait chier avec plein de petits détails galère.

Eureka

Je me dirige alors vers la recherche d'outils Open Source gérant cela (je sais j'ai fait les choses a l'envers faites pas chier, c'est ma fierté mal placée) franchement pas convaincu de trouver un truc pareil en libre.
Je commence donc a arpenter le wiki de voip-info et a essayer divers trucs plus ou moins réussis, plus ou moins payants, plus ou moins ininstallables.
Et la je tombe sur A2biling ,LE TRUC DE LA MORT QUI TUE SA RACE, le produit PHP/MySQL qui gere non seulement tout ce que je cherche mais meme dix fois plus (prépayé,postpayé,identification par CID,recharge de cartes...)!



Apres 3 saltos arriere, une danse du ventre et 1/4 d'heure d'installation sans encombres (franchement génial le wiki http://wiki.asterisk2billing.org/index.php/Installation_guide , je n'ai fait que le suivre a la lettre ) le truc est direct opérationnel et la c'est franchement la folie au niveau de l'ergonomie et de la simplicité de mise en route.

  • Tu crées tes utilisateurs (cartes) qui sont authentifiés soit par leur CID soit par un code a taper.
  • Tu crées tes cartes prepayées, tout est paramétrable.
  • Tu crées tes offres
  • Tu sors des stats, des factures ...
  • Bref une multitude de fonctionnalités (dont je suis loin d'avoir faite le tour tellement c'est vaste)
Vous avez compris je suis fan de a2billing et je vous encourage vivement a aller le tester

http://www.asterisk2billing.org/cgi-bin/trac.cgi

mercredi 2 juillet 2008

Mes sources d'informations Asterisk

A tout seigneur tout honneur , je me dois de remercier les sources qui me permettent d'avancer avec Asterisk depuis mes premiers pas (3 ans déjà!)

L'incontournable voip-info avec son wiki, bible d'Asterisk
Astrecipes , très sympa aussi
Asterisk France
Asterisk guru
Le topic Asterisk d'HFR
Site Officiel

Sans oublier le lien vers LE DOCUMENT DE RÉFÉRENCE sur Asterisk
Asterisk, the future of Telephony@O'Reilly

Petit script en php utilisant le manager Asterisk pour lancer un appel

Script établissant une communication entre deux extensions

if($_POST['lancer'])

{

$appelle=$_POST['extension'];

$appelant=$_POST['sipuser'];

echo "$appelant vous allez être en communication avec le ".$appelle;

// connexion au manager

$socket = fsockopen("xxxxxx","5038", $errno, $errstr);

fputs($socket, "Action: Login\r\n");

fputs($socket, "UserName: superuser\r\n");

fputs($socket, "Secret: xxxxxx\r\n\r\n");

fgets($socket);

// lancement de l'appel

fputs($socket, "Action: Originate\r\n");

fputs($socket, "Exten: $appelle\r\n");

fputs($socket, "Context: yyyyyyy\r\n");

fputs($socket, "CallerID: $appelle\r\n");

fputs($socket, "Priority: 1\r\n");

fputs($socket, "Channel: SIP/$appelant\r\n\r\n");

fputs($socket, "Action: Logoff\r\n");

}

Commander Asterisk avec des fichiers .call

L'utilisation des fichiers .call avec Asterisk


Il existe une autre manière de lancer des applications avec Asterisk, l’utilisation de fichiers .call.

En déposant dans le répertoire /var/spool/asterisk/outgoing des fichiers correctement formatés, il est possible de déclencher des applications d’Asterisk, qui scanne continuellement ce répertoire.

Exemple 1 : Envoi de SMS via un fichier call

Envoie un SMS au yyyyyyyyy en utilisant la passerelle de bezeq (14974800), nécessite un contexte [smsdial] (voir extensions.conf)

Channel: ZAP/g1/14974800

MaxRetries: 1

RetryTime: 60

WaitTime: 30

Context: smsdial

Extension: yyyyyyyyy

Priority: 1

SetVar: MSG=Test SMS coucou

Il est également possible d’utiliser le programme smsq en ligne de commande pour envoyer un SMS ;

smsq --motx-channel= numero_du_centre sur le channel numero_du_destinanataire "test"

Exemple 2 : Envoi de FAX via un fichier call

Envoie le document stocke dans /var/spool/asterisk/fax/1179405466.6.tif en fax au numéro XXXXXXX

Channel:ZAP/g1/XXXXXX

MaxRetries: 1

WaitTime: 20

Application:txfax

Data:/var/spool/asterisk/fax/1179405466.6.tif|caller

Script , capable de générer des fichier call creeficcall :

#!/bin/sh

# SL 20/05/2007 SCRIPT d'envoi de fax/sms

# cree dans le repertoire outgoing un fichier .call executant l'operation

CONCENTRATEUR_SMS=14974800

CHEMIN_FICHIER_CALL="/var/spool/asterisk/outgoing/"

POOL_FAX="/var/spool/asterisk/fax/"

typemessage=$1

destinataire=$2

corps=$3

if [ $1 = 'SMS' ]

then

echo "Channel: ZAP/g1/"$CONCENTRATEUR_SMS"

MaxRetries: 1

RetryTime: 60

WaitTime: 30

Context: smsdial

Extension: "$2"

Priority: 1

SetVar: MSG="$3 > $CHEMIN_FICHIER_CALL$1"_"$2".call"

fi

if [ $1 = 'FAX' ]

then

echo "Channel: ZAP/g1/"$2"

MaxRetries: 1

WaitTime: 20

Application:txfax

Data:"$POOL_FAX$3"|caller" > $CHEMIN_FICHIER_CALL$1"_"$2".call"

fi

if [ $1 = 'VOICEMAIL' ]

then

echo "Channel: SIP/"$2"

MaxRetries: 1

WaitTime: 20

Set:CHANNEL(language)=fr

Application:VoiceMailMain

Data:"$3 > $CHEMIN_FICHIER_CALL$1"_"$2".call"

fi