= Photo de famille aka 'Big picture' =
Pour un téléphone (encore dans son emballage) à attribuer/déployer/allouer, vous ouvrez une interface web (ou lancez un script CLI) muni de votre douchette code barre (genre douchette USB clavier à deux balles ... Vous n'en avez pas? Bah tappez l'adresse MAC, c'est pas très difficile non plus):
* vous lisez l'adresse MAC code barre sur le carton avec la douchette dans le champ qui a le focus (ou le prompt CLI),
* vous remplisser les autres champs variables (numéros de téléphone, Prénoms et Nom de l'usager, type de téléphone, etc)
* vous validez.
L'application django/YMMV effectue les opérations suivantes:
* Enregistre/met à jour les informations dans la base
* Si vous utilisez asterisk realtime alors rien à faire en plus à ce niveau
* Sinon il gènère le block peer à inclure dans sip.conf/voicemail.conf/extensions.conf, etc (On pourra utiliser inotify pour le 'sip reload' pour éviter les problèmes de perms, exemple de script ci-dessous)
* Utilise le moteur de template interne (ou Jinja) pour génèrer à partir de la template le fichier à télécharger en tftp par le téléphone dés qu'il sera connecté au réseau
Dés que le téléphone est connecté, il télécharge son fichier identifié par son MAC après la danse DHCP et il est prêt à opérer.
= Modèle Django et schéma asterisk =
Les modèles django sont plus ou moins calqués sur les schéma utilisés par les différents pilotes de stockage utilisés par “Asterisk Realtime Architecture" ARA ([[http://www.voip-info.org/wiki/view/Asterisk+RealTime|http://www.voip-info.org/wiki/view/Asterisk+RealTime]] Dommage mais bon ça va changer un jour aussi grâce à ce que Tom apelle l'effet Obama Heu!)
{{{
#-*- coding: utf-8 -*-
from django.db import models
from django.db import models
from django.contrib import admin
from django.template.loader import render_to_string
from django.template import loader, Context
from django.utils.encoding import smart_str
from datetime import datetime
# Le mot de passe utilisé par le téléphone pour s'authentifier auprès
# d'Asterisk, Bah qui en a besoin en dehors des deux parties?
def make_pass():
return 'Pas très difficile de générer des mots de passe du tout'
# celui-ci a l'id qui va bien comme serial deja
class ExtensionsConf(models.Model):
context = models.CharField(blank=True, null=True, max_length=256)
exten = models.CharField(blank=True, null=True, max_length=256)
priority = models.CharField(blank=True, null=True, max_length=256)
app = models.CharField(blank=True, null=True, max_length=256)
appdata = models.CharField(blank=True, null=True, max_length=1024)
class Meta:
db_table = u'extensions_conf'
admin.site.register(ExtensionsConf)
class VoicemailUsers(models.Model):
customer_id = models.IntegerField(default=0)
context = models.CharField(blank=True, null=True, max_length=50)
mailbox = models.CharField(max_length=32)
password = models.CharField(max_length=8, default='0000')
fullname = models.CharField(blank=True, null=True, max_length=50)
email = models.CharField(blank=True, null=True, max_length=50)
pager = models.CharField(blank=True, null=True, max_length=50)
stamp = models.DateTimeField(default=datetime.now)
class Meta:
db_table = u'voicemail_users'
admin.site.register(VoicemailUsers)
class SipConf(models.Model):
adresse_mac = models.CharField(“Adresse MAC (Douchette ou sans les ':' )”, max_length=128)
# Ceci détermine la template à utiliser pour le fichier de conf
type_telephone = models.CharField(u'Type de téléphone', max_length=128, choices=(('st20XX', 'Thomson ST 20XX'), ('922', 'SPA 922'), ('942', 'SPA 942'), ('962', 'SPA 962'), ('962+932', 'SPA 962+932'), ('962+932+932', 'SPA 962+932+932'), ('ip6000', 'SoundStation IP 6000')), default='922')
adresse_ip = models.CharField('Adresse IP', max_length=128)
mask_sr = models.CharField('Masque de sous réseau', max_length=128, default='255.255.255.0')
passerelle = models.CharField('Passerelle par défaut', max_length=128, default='192.168.167.254')
dns_primaire = models.CharField('DNS', max_length=128, default='192.168.167.100')
username = models.CharField('N° Téléphone', blank=True, null=True, max_length=128)
callerid = models.CharField('Nom complet', blank=True, null=True, max_length=128)
serveur_sip = models.CharField('Serveur Téléphonie', max_length=128, default='192.168.167.67')
secret = models.CharField(blank=True, null=True, max_length=128, default=make_pass)
context = models.CharField(blank=True, null=True, max_length=128, default='default', choices=(('default', 'Interne'), ('national', 'Na
tional'), ('portable', 'Portable'), ('inter', 'International')))
# Bah le reste on s'en occupe, dans le genre touchez plus à rien au delà
# de cette ligne à moins que vous ne savhiez vraiment ce que vous faites :)
serveur_log = models.CharField('Serveur journal', blank=True, null=True, max_length=128)
serveur_prov = models.CharField('Serveur Provisionning', max_length=128)
dns_secondaire = models.CharField(blank=True, null=True, max_length=128)
name = models.CharField(blank=True, null=True, max_length=128)
accountcode = models.CharField(blank=True, null=True, max_length=20)
amaflags = models.CharField(blank=True, null=True, max_length=7)
callgroup = models.CharField(blank=True, null=True, max_length=10)
canreinvite = models.CharField(default='yes', max_length=3)
defaultip = models.CharField(blank=True, null=True, max_length=15)
dtmfmode = models.CharField(blank=True, null=True, max_length=7)
fromuser = models.CharField(blank=True, null=True, max_length=128)
fromdomain = models.CharField(blank=True, null=True, max_length=128)
host = models.CharField(blank=True, null=True, max_length=31, default='dynamic')
insecure = models.CharField(blank=True, null=True, max_length=4)
language = models.CharField(blank=True, null=True, max_length=2, default='fr')
mailbox = models.CharField(blank=True, null=True, max_length=50)
md5secret = models.CharField(blank=True, null=True, max_length=128)
nat = models.CharField(default='no', max_length=5)
permit = models.CharField(blank=True, null=True, max_length=95)
deny = models.CharField(blank=True, null=True, max_length=95)
mask = models.CharField(blank=True, null=True, max_length=95)
pickupgroup = models.CharField(blank=True, null=True, max_length=10)
port = models.CharField(blank=True, null=True, max_length=5)
qualify = models.CharField(blank=True, null=True, max_length=3)
restrictcid = models.CharField(blank=True, null=True, max_length=1)
rtptimeout = models.CharField(blank=True, null=True, max_length=3)
rtpholdtimeout = models.CharField(blank=True, null=True, max_length=3)
type = models.CharField(default='friend', max_length=25)
disallow = models.CharField(default='all', max_length=1024)
allow = models.CharField(default='g729;ilbc;gsm;ulaw;alaw', max_length=100)
musiconhold = models.CharField(blank=True, null=True, max_length=100)
regseconds = models.IntegerField(default=0)
ipaddr = models.CharField(blank=True, null=True, max_length=128)
regexten = models.CharField(blank=True, null=True, max_length=128)
cancallforward = models.CharField(default='yes', max_length=3)
call_limit = models.CharField(default='99', max_length=10, db_column='call-limit')
limitonpeers = models.CharField(default='yes', max_length=10)
fullcontact = models.CharField(blank=True, null=True, max_length=256)
cur_ip = models.CharField(blank=True, null=True, max_length=256)
prenoms = models.CharField(u'Prénoms', blank=True, null=True, max_length=256)
nom = models.CharField(u'Nom', blank=True, null=True, max_length=256)
fonction = models.CharField(u'Fonction', blank=True, null=True, max_length=256)
site = models.CharField(u'Site', blank=True, null=True, max_length=256)
nom_court = models.CharField(u'Nom court', blank=True, null=True, max_length=256)
email = models.EmailField(blank=True, null=True)
class Meta:
db_table = u'sip_conf'
def _mac(self):
return (":".join([self.adresse_mac[i:i+2] for i in range(0,len(self.adresse_mac), 2)])).upper()
mac = property(_mac)
def __unicode__(self):
return u"%s <%s>" %(self.callerid, self.username)
def save(self):
import time
from commands import getoutput
if not self.callerid:
self.callerid = u"%s %s" % (self.prenoms, self.nom)
if not self.nom_court:
self.nom_court = "%s. %s" %(". ".join([s[0] for s in self.prenoms.split()]), self.nom.upper())
self.adresse_mac = self.adresse_mac.lower()
if not self.serveur_log:
self.serveur_log = self.serveur_sip
if not self.serveur_prov:
self.serveur_prov = self.serveur_sip
if not self.mailbox:
self.mailbox = self.username
if not self.secret:
self.secret = make_pass()
if not self.name:
self.name = self.username
if not self.host:
self.host = 'dynamic'
# Ok on Sauve, ce qui nous donne le compte SIP en même temps
super(SipConf, self).save()
# On génère le fichier de provisionninhg
postes = [] # Les postes pour un subscribe/notify/blf par exemple
print self.type_telephone
postes = None ≈
try:
fd = open('/tftpboot/%s.cfg'% self.adresse_mac, 'w')
t = loader.get_template('spa-%s.html'% self.type_telephone)
c = Context({'u': self, 'postes':postes})
bstring = t.render(c)
fd.write(smart_str(bstring))
fd.close()
except Exception, e:
print e # Allez mieux que print quand même
# On génère les extensions associées ... En fait on fait généralement
# pas ça, il y a un catchall pour les numéros internes
pr1, created = ExtensionsConf.objects.get_or_create(context=self.context, exten=self.username, priority='1')
pr1.app = 'Dial'
pr1.appdata = 'SIP/%s' % self.username
pr1.save()
# Présence par exmple
pr2, created = ExtensionsConf.objects.get_or_create(context=self.context, exten="%s" % self.username, priority='hint')
pr2.app='SIP/%s' %self.username
pr2.appdata = ''
pr2.save()
# On génère le Voicemail associé
vm, created = VoicemailUsers.objects.get_or_create(context='omvs', mailbox=self.username)
vm.fullname = self.callerid
vm.save()
m_extens = open('/tmp/subscribe.conf', 'w')
m_extens.write('\n'.join([ "exten => %s,hint,%s"%(e.exten, e.app) for e in ExtensionsConf.objects.filter(priority='hint')]))
m_extens.close()
admin.site.register(SipConf)
}}}
= Vues Django =
Quelques vues basiques permettant d'avoir la liste des comptes et d'ajouter de nouveaux comptes:
views.py
{{{
#-*- coding: utf-8 -*-
from django.forms import ModelForm, ValidationError
from django.template import Context, loader
from django.utils.encoding import force_unicode
from django.utils.encoding import smart_str, smart_unicode
from django.contrib.auth.decorators import user_passes_test, login_required
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.core.exceptions import ObjectDoesNotExist
from noyau.models import ExtensionsConf, SipConf
class SipModelForm(ModelForm):
class Meta:
model = SipConf
fields = ('prenoms',
'nom',
'fonction',
'site',
'adresse_mac',
'type_telephone',
'adresse_ip',
'cur_ip',
'mask_sr',
'passerelle',
'dns_primaire',
'username',
'callerid',
'serveur_sip',
'context')
def clean_adresse_mac(self):
if 'adresse_mac' in self.cleaned_data:
if len(self.cleaned_data['adresse_mac']) != 12 :
raise ValidationError(u"L'adresse MAC fournit n'est pas valide, n'omettez pas les zéros")
return self.cleaned_data['adresse_mac']
@login_required
def siplist(request, action):
if action == 'list':
return render_to_response('sip/list.html', {'users':SipConf.objects.filter(site__startswith='02').order_by('username') })
if request.method == 'POST':
form = SipModelForm(request.POST)
if form.is_valid():
new_user = form.save()
return HttpResponseRedirect('/sip/list/')
else:
form = SipModelForm()
return render_to_response('sip/add.html', {'form': form})
@login_required
def sipuser(request, action, id):
try:
user = SipConf.objects.get(pk=int(id))
except ObjectDoesNotExist:
return HttpResponseRedirect('/sip/list/')
if action == 'delete':
user.delete()
return HttpResponseRedirect('/sip/list/')
if request.method == 'POST':
form = SipModelForm(request.POST, instance=user)
if form.is_valid():
new_user = form.save()
return HttpResponseRedirect('/sip/list/')
else:
form = SipModelForm(instance=user)
return render_to_response('sip/edit.html', {'form': form})
sip/add.html
IP Phone Deploy
Ajouter un poste à l'implantation
sip/edit.html
IP Phone Deploy
Editer un poste de l'implantation
sip/list.html
Proxima C. IPBX v2
Liste des postes de l'implantation
Ajouter un poste
MAC | Type | Numéros | Nom | IP | Site | _ | _ | _ |
{% for u in users %}
{{ u.mac }} |
{{ u.type_telephone }} |
{{ u.username }} |
{{ u.callerid }} |
{{ u.adresse_ip }} |
{{ u.site }} |
Recharger
| Upgrade
| Supprimer |
{% endfor %}
}}}
= Templates de configuration =
Dans le cas des ST 20XX, les fichiers templates dont on peut se servir sont (Page 88 du guide d'Admin):
* File Inf contient les chemins d'accès aux différents fichiers
'''Example of file INF SIP''':
Exemple:
{{{
[provision_mode]
provision_mode=auto_provisioning
[application]
fw_filename=st2030SEG_fw.zz
dsp_filename=v2030_dsp_ver_.zz
boot_filename=v2030_boot_ver.zz
[config]
telcfg=TelConf2030SEG_telcfg.txt
common_config=st2030s_common.txt
melodies=Melodies.txt
system_melodies=S_Melodies.txt
call_waiting_tone=ringtone.txt
tone_table=ToneTb.txt
language_table=langtable.txt
}}}
* Firmware: Code de version à charger par le téléphone
* common_config: Informations concernant tous les téléphone (généralement config réseau SIP, autoprov, etc)
Ce fichier va contenir un ensemble de paramètres varaibles qui seront remplacé par le moteur de template en fonction du contexte qui lui sera passé.
Exemple:
{{{
[ipp]
AutoAnsMode= {{ mode_auto_answer }}
AutoAnsTimer=0
Autocall=0
AutocallNumber=
AutoRejectTimer=0
AutoStopTimer=0
AutoHangUpTimer=3
CaLogPrefix=
Check_phonebook_domain_name=1
Disable_call_progress=0
Hide_Phone_Number_Display=0
HideMissedCall=0
LanguageType=0
LocalMusicOnHold=1
ManualLog=0
OptionVisible=8191
PasswordString=0000
PhoneLock=0
Pick_up_call=1
Ringer_default_vol=4
Ringer_lock=0
RingToneMP1=0
RingToneMP2=0
RingToneMP3=0
RingToneMP4=0
Suppress-DomainName-Flag=1
Transfer_to_voice_mail=1
TransfOnRingFlag=0
[net]
DNSSrv1=0.0.0.0
DNSSrv2=0.0.0.0
DNSFLG=1
DSCPflag=0
ESWITCH_LAN=1
ESWITCH_PC=1
Gateway=0.0.0.0
ipwan=10.1.24.88
IpDFflag=0
MaskWan=0.0.0.0
PersistentVLANfromDHCP=0
TelnetTime=240
TelnetSrv=1
VLAN=0
WanModFlag=1
[pstn]
[sip]
ACD=0
AuthMessageServer=0.0.0.0
KeppAliveDest=0.0.0.0
KeepAliveTimer=0
AuthNotifyCheckSync=0.0.0.0
CallBlockType=0
CF_Address1=
CFNA_Time1=30
CF_domain=
ConnectReuseFlgMP1=0
ConnectReuseFlgMP2=0
ConnectReuseFlgMP3=0
ConnectReuseFlgMP4=0
ConnectReuseFlgBK1=0
ConnectReuseFlgBK2=0
ConnectReuseFlgBK3=0
ConnectReuseFlgBK4=0
ConferenceMode=0
ConferenceFactoryURI=conf
CallParkType=0
CLIPDisplayPrior=ppreferred(1)passerted(2)remoteparty(3)from(4)
CalledDisplayPrior=dialed(1)passerted(2)remoteparty(3)
CallPkupFlg=local
CallPkupSC=
CallFwdFlg=local
CallFwdOffSC=
CallFwdAlwaysSC=
CallFwdBusySC=
CallFwdNoAnswerSC=
CallParkFlg=local
CallParkSC=
CallRetreiveSC=
CallBlockFlg=local
CallBlockAllowSC=
CallBlockRejectSC=
CallBlockOFFSC=
ClirFlg=local
ClirOnSC=
ClirOffSC=
CallWaitingFlg=local
CallWaitingOnSC=
CallWaitingOffSC=
call_hold_method=0
CFUOnSV=
CFUOffSV=
DisplayNumFlag1=0
DisplayNumFlag2=0
DisplayNumFlag3=0
DisplayNumFlag4=0
DisplayNum1=
DisplayNum2=
DisplayNum3=
DisplayNum4=
DNDFlg=local
DNDOnSC=
DNDOffSC=
DNDOnSV=
DNDOffSV=
DNDResp=1
DisplayName1=
DisplayName2=
DisplayName3=
DisplayName4=
DisplayNameFlag1=0
DisplayNameFlag2=0
DisplayNameFlag3=0
DisplayNameFlag4=0
DiversionHeaderFlag=0
ExpireTimeMP1=3600
ExpireTimeMP2=3600
ExpireTimeMP3=3600
ExpireTimeMP4=3600
ExpireTimeBK1=3600
ExpireTimeBK2=3600
ExpireTimeBK3=3600
ExpireTimeBK4=3600
Earlymediatype=0
HGOnSC=
HGOffSC=
HGOnSV=
HGOffSV=
MissedCallSummary=0
OutBoundProxy0=
OutBoundPort0=5060
OutBoundType=0
ProfileName1=Profile 1
ProfileName2=Profile 2
ProfileName3=Profile 3
ProfileName4=Profile 4
PrivacyFlag1=4
ProxyServerMP1=
ProxyServerMP2=
ProxyServerMP3=
ProxyServerMP4=
ProxyServerBK1=
ProxyServerBK2=
ProxyServerBK3=
ProxyServerBK4=
P-AssertedIDforCallee=0
regid1= {{ username }}
regid2=
regid3=
regid4=
regpwd1=
regpwd2=
regpwd3=
regpwd4=
RegisterServerMP1=
RegisterServerMP2=
RegisterServerMP3=
RegisterServerMP4=
RegisterServerBK1=
RegisterServerBK2=
RegisterServerBK3=
RegisterServerBK4=
RtpPort=41000
ReTransTimer1=500
ReTransTimer2=4
RegisterFrequencyMP1=600
RegisterFrequencyMP2=600
RegisterFrequencyMP3=600
RegisterFrequencyMP4=600
RegisterFrequencyBK1=600
RegisterFrequencyBK2=600
RegisterFrequencyBK3=600
RegisterFrequencyBK4=600
REQ_RUI_with_port=1
RFC2833=1
RFC2833_rtp_pltype=96
RFC3262=0
RandomCSeqFlag=0
SubscribeDilaogBeforeLogin=1
RandomRTPPortFlag=0
RegEventServer=
ServiceDomainMP1=
ServiceDomainMP2=
ServiceDomainMP3=
ServiceDomainMP4=
ServiceDomainBK1=
ServiceDomainBK2=
ServiceDomainBK3=
ServiceDomainBK4=
SessionExpire=1800
SessionExpireMin=100
SessionMethod=0
SessionRefresher=0
sip_portMP1=5060
sip_portMP2=5060
sip_portMP3=5060
sip_portMP4=5060
sip_portBK1=5060
sip_portBK2=5060
sip_portBK3=5060
sip_portBK4=5060
sip_reg_srv_portMP1=5060
sip_reg_srv_portMP2=5060
sip_reg_srv_portMP3=5060
sip_reg_srv_portMP4=5060
sip_reg_srv_portBK1=5060
sip_reg_srv_portBK2=5060
sip_reg_srv_portBK3=5060
sip_reg_srv_portBK4=5060
sip_pxy_srv_portMP1=5060
sip_pxy_srv_portMP2=5060
sip_pxy_srv_portMP3=5060
sip_pxy_srv_portMP4=5060
sip_pxy_srv_portBK1=5060
sip_pxy_srv_portBK2=5060
sip_pxy_srv_portBK3=5060
sip_pxy_srv_portBK4=5060
SubscriptionExpire=3600
SubscriptionExpireCB=60
SharedCallAppearance=0
SCAMainLinePrivate=0
Specific_IP_flag=0
HeaderCompact=0
subscribe_event=0
sw_anon_reject=0
sw_CF=0
sw_CFA=0
sw_CFNA=0
sw_CFB=0
sw_not_disturb=0
sw_call_park=0
sw_notify_autoprovision=0
sw_tr_vmail_address1=
sw_tr_vmail_address2=
sw_tr_vmail_address3=
sw_tr_vmail_address4=
sw_tr_vmail_flag=0
sw_park_srv_addr1=
sip_instance_id=0
SFOnSC=
SFOffSC=
SFOnSV=
SFOffSV=
TransferOnRingSC=
TrVoiceMailFlg0=local
TrVoiceMailFlg1=local
TrVoiceMailFlg2=local
TrVoiceMailFlg3=local
TrVoiceMailFlg4=local
TrVoiceMailOnSC0=
TrVoiceMailOnSC1=
TrVoiceMailOnSC2=
TrVoiceMailOnSC3=
TrVoiceMailOnSC4=
TrVoiceMailOffSC0=
TrVoiceMailOffSC1=
TrVoiceMailOffSC2=
TrVoiceMailOffSC3=
TrVoiceMailOffSC4=
TrVoiceMailRingSC0=
TrVoiceMailRingSC1=
TrVoiceMailRingSC2=
TrVoiceMailRingSC3=
TrVoiceMailRingSC4=
TEL1Number=
TEL2Number=
TEL3Number=
TEL4Number=
TransportFlgMP1=0
TransportFlgMP2=0
TransportFlgMP3=0
TransportFlgMP4=0
TransportFlgBK1=0
TransportFlgBK2=0
TransportFlgBK3=0
TransportFlgBK4=0
TransferUseContact=1
URLTypeMP1=0
URLTypeMP2=0
URLTypeMP3=0
URLTypeMP4=0
URLTypeBK1=0
URLTypeBK2=0
URLTypeBK3=0
URLTypeBK4=0
USRPhoneFlg=1
UnRegister_priorFlgMP1=1
UnRegister_priorFlgMP2=1
UnRegister_priorFlgMP3=1
UnRegister_priorFlgMP4=1
UnRegister_priorFlgBK1=1
UnRegister_priorFlgBK2=1
UnRegister_priorFlgBK3=1
UnRegister_priorFlgBK4=1
use_PrivateNumber=0
VoiceMailAddr=
VoiceMailTelNum=
VoiceMailPort=5060
[snmp]
commRW1=0
commRW2=0
commRW3=0
flag=1
filter=0
snmpManager1=0.0.0.0
snmpManager2=0.0.0.0
snmpManager3=0.0.0.0
snmpManager4=0.0.0.0
snmpManager5=0.0.0.0
sysTrapSrv=0.0.0.0
sysCommName1=public
sysCommName2=
sysCommName3=
sysContact=Thomson
sysDescr=Thomson IP Phone
sysLocation=France
sysName=ST2030 SIP
TrapLevel=0
[sys]
2833_volume=0
AEC=1
BLFType=0
BLFListSipUri=L/
CountryCode=US
config_sn=200402190001
Current_Max_Multiline=10
CodecJitterBufMult=g711a(1/2/4)g711mu(1/2/4)g729(1/2/4)g723(1/2/4)
CodecPktime=g711a(10)g711mu(10)g729(10)g723(30)
CodecAdaptivePlayout=g711a(1)g711mu(1)g729(1)g723(1)
DisableCWtone=0
Dialednum_timeout=4
dtmf_mode_flag=1
EmergencyDialPlan=|911|11x|1[2-8]|
FeatureKeyExt01=L/
FeatureKeyExt02=L/
FeatureKeyExt03=L/
FeatureKeyExt04=L/
FeatureKeyExt05=L/
FeatureKeyExt06=L/
FeatureKeyExt07=L/
FeatureKeyExt08=L/
FeatureKeyExt09=L/
FeatureKeyExt10=L/
FeatureKeyExt11=L/
FeatureKeyExt12=L/
FeatureKeyExt13=L/
FeatureKeyExt14=L/
FeatureKeyExt15=L/
FeatureKeyExt16=L/
FeatureKeyExt17=L/
FeatureKeyExt18=L/
FeatureKeyExt19=L/
FeatureKeyExt20=L/
FeatureKeyExt21=L/
FeatureKeyExt22=L/
FeatureKeyExt23=L/
FeatureKeyExt24=L/
FeatureKeyExt25=L/
FeatureKeyExt26=L/
FeatureKeyExt27=L/
FeatureKeyExt28=L/
FeatureKeyExt29=L/
FeatureKeyExt30=L/
FeatureKeyExt31=L/
FeatureKeyExt32=L/
FeatureKeyExt33=L/
FeatureKeyExt34=L/
FeatureKeyExt35=L/
FeatureKeyExt36=L/
FeatureKeyExt37=L/
FeatureKeyExt38=L/
FeatureKeyExt39=L/
FeatureKeyExt40=L/
FeatureKeyExt41=L/
FeatureKeyExt42=L/
FeatureKeyExt43=L/
FeatureKeyExt44=L/
FeatureKeyExt45=L/
FeatureKeyExt46=L/
FeatureKeyExt47=L/
FeatureKeyExt48=L/
FeatureKeyExt49=L/
FeatureKeyExt50=L/
FeatureKeyExt51=L/
FeatureKeyExt52=L/
FeatureKeyExt53=L/
FeatureKeyExt54=L/
FeatureKeyExt55=L/
FeatureKeyExt56=L/
FeatureKeyExt57=L/
FeatureKeyExt58=L/
FeatureKeyExt59=L/
FeatureKeyExt60=L/
FeatureKeyExt61=L/
FeatureKeyExt62=L/
FeatureKeyExt63=L/
FeatureKeyExt64=L/
FeatureKeyExt65=L/
FeatureKeyExt66=L/
FeatureKeyOpt01=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt02=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt03=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt04=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt05=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt06=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt07=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt08=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt09=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt10=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt11=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt12=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt13=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt14=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt15=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt16=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt17=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt18=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt19=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt20=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt21=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt22=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt23=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt24=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt25=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt26=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt27=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt28=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt29=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt30=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt31=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt32=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt33=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt34=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt35=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt36=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt37=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt38=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt39=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt40=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt41=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt42=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt43=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt44=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt45=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt46=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt47=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt48=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt49=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt50=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt51=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt52=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt53=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt54=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt55=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt56=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt57=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt58=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt59=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt60=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt61=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt62=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt63=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt64=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt65=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
FeatureKeyOpt66=dialog(1)regDND(0)ua-profile(0:cfu(0)dnd(0)sf(0)hg(0))
NormalDigitFlag=1
PCallLogURL=
PSettingURLdl=
PSettingURLul=
Phonebook1_url=
Phonebook2_url=
Phonebook3_url=
Phonebook4_url=
Phonebook5_url=
Phonebook6_url=
Phonebook7_url=
Phonebook8_url=
Phonebook1_name=
Phonebook2_name=
Phonebook3_name=
Phonebook4_name=
Phonebook5_name=
Phonebook6_name=
Phonebook7_name=
Phonebook8_name=
PBXconfiguration=0
PBXprefix=
softkey01=TrVoiceMail
softkey02=CallLog
softkey03=PickUp
softkey04=LockPhone
softkey05=VoiceMail
softkey06=RetrievePark
softkey07=DNDstate
softkey08=ShortCut1
softkey09=ShortCut2
softkey10=ACDCheckIn
softkey11=ACDAvailable
softkey12=Login
StartSpareFK=0
ServiceSupervisionFK=11
ServiceSupOrder=callfwd(0)dnd(0)secfilter(0)huntgroup(0)
SuppressRTCP=0
TelnetID=administrator
TelnetPWD=789234
UserID=user
UserPWD=
VOIPDialPlan=x.T
WebPWD=784518
[autoprovision]
AutoprovisionFlag=1
AutoprovisionHTTPServer=
AutoprovisionTFTPServer=
AutoprovisionTimeDays=0
Autoprovisionstarttime=00:00
AutoprovisionTimeSpan=0
AutoprovisionRetryPeriod=30
[qos]
DHCPVLANid1=1
DHCPVLANid2=1
DSCP1=46
DSCP2=40
DSCPdata=40
TOS=160
VLANid1=1
VLANid2=1
VLANTag1=6
VLANTagdata=6
[ftp]
FTPID=
FTPPWD=
[ntp]
NtpDaylight=1
NTPFlag=0
NtpIP= {{ serveur_ntp }}
NtpMode=0
NtpSyncTime=1
NtpZoneNum=23
[pppoe]
PPPoEID=
PPPoELCPMod=2
PPPoELCPTimer=60
PPPoEPWD=
PPPoEMTU=1454
[stun]
STUNSrv=
STUNPort=0
STUNFlag=0
[upnp]
UPnPFlag=1
[customer]
sw_call_wait=1
}}}
* -config: Informations spécifiques au téléphone dont le mac est spécifié
Identique au fichier précédant, sauf qu'il faut mettre à jour le numéros de série pour chaque APS (config_sn=xxxxxxxxxxxx)
* TelConf: paramètres audio génériques
Il est recommandé de ne pas le changer disent-ils Heu!
= Preuve du concept en CLI =
Qui s'y colle? Pour utiliser Django en script il suffit d'ajouter ces quelques lignes au début pour accèder au projet Django:
{{{
import os, sys, email
rep_projet = '/usr/local/voip_projets'
nom_projet = 'ipphonedeploy'
modules_projet = __import__(nom_projet, '', '', [''])
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
}}}
= Idées de migration de peers asterisk =
L'idée ce serait de parser le sip.conf/iax.conf et d'en extraire les comptes pour les insérer dans la base, ensuite il faudra juste leurs allouer les adresses MAC associées.
= Script inotify pour asterisk -rx "sip reload" =
{{{
try:
# import local build
import autopath
from src.pyinotify.pyinotify import ThreadedINotify, EventsCodes
except ImportError:
# import global (installed) pyinotify
from pyinotify import ThreadedINotify, EventsCodes
from pyinotify import ProcessEvent
from commands import getoutput
from datetime import datetime
class ProcessAsterisk(ProcessEvent):
def process_default(self, event_k, event):
pass
def process_IN_MODIFY(self, event_k):
print '_IN_CREATE'
astatus = getoutput("/usr/sbin/asterisk -rx 'sip reload'")
def process_IN_OPEN(self, event_k):
pass
def process_IN_CREATE(self, event_k):
print '_IN_CREATE'
astatus = getoutput("/usr/sbin/asterisk -rx 'sip reload'")
if __name__ == '__main__':
import sys
path = '/home/watchasteriskconfig' # default watched path
if sys.argv[1:]:
path = sys.argv[1]
# only watch those events
mask = EventsCodes.IN_MODIFY | EventsCodes.IN_DELETE | \
EventsCodes.IN_OPEN | EventsCodes.IN_ATTRIB | \
EventsCodes.IN_CREATE
# class instance and init
ino = ThreadedINotify()
# start thread
ino.start()
ino.add_watch(path, mask, ProcessAsterisk())
print 'start monitoring %s with mask %d' % (path, mask)
# keep artificially the main thread alive forever
while True:
try:
import time
time.sleep(5)
except KeyboardInterrupt:
# ...until c^c signal
print 'stop monitoring...'
ino.stop()
break
except Exception, err:
# otherwise keep on looping
print err
}}}
= Configuration DHCP (d'après la DOC page 87) =
{{{
option tftp-server-name "@IP serveur TFTP"; --------------> option 66
option bootfile-name "nomDeFichierINF.txt"; --------------> option 67
option provision-server-ip code 150 = text ------------->option 150 is text, not binary mode
option provision-server-ip "@IP serveur TFTP "; -------------> next server address
option vendor-encapsulated-options "http://192.168.70.10/swupgrade_st2030m.txt" ---->option 43
}}}
----
[[CatégorieVoIP]]
----
[[CatégorieVoIP]]