= 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

{{ form }}

sip/edit.html IP Phone Deploy

Editer un poste de l'implantation

{{ form }}

sip/list.html Proxima C. IPBX v2

Liste des postes de l'implantation

Ajouter un poste

{% for u in users %} {% endfor %}
MACTypeNumérosNomIPSite___
{{ u.mac }} {{ u.type_telephone }} {{ u.username }} {{ u.callerid }} {{ u.adresse_ip }} {{ u.site }} Recharger Upgrade Supprimer
}}} = 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]]