Anda di halaman 1dari 77

PENDAHULUAN

1.1 Pengertian VOIP. VoIP (Voice over Internet Protocol) merupakan nama lain internet telephony. Internet telephony adalah hardware dan software yang memungkinkan pengguna Internet untuk media transmisi panggilan telepon. Kualitas Internet telephony ini belum sebaik kualitas koneksi telepon langsung. Voice over Internet Protocol (VoIP) adalah teknologi yang mampu melewatkan trafik suara, video dan data yang berbentuk paket melalui jaringan IP. Dalam komunikasi VoIP, pemakai melakukan hubungan telepon melalui terminal yang berupa PC atau telepon. Terminal akan berkomunikasi dengan gateway melalui telefoni lokal. Hubungan antar gateway dilakukan melalui network IP. Network IP dapat berupa network paket apapun, termasuk ATM, FR, Internet, Intranet, atau line E1. VoIP menawarkan transportasi sinyal yang lebih murah, feature tambahan, dan transparansi terhadap data komputer. Hambatan VoIP saat ini adalah kehandalannya yang di bawah telefoni biasa, dan soal standarisasi yang akan menyangkut masalah interoperabilitas.

1.2 KEUNTUNGAN MENGGUNAKAN VOIP Dengan bertelepon menggunakan VoIP, banyak keuntungan yang dapat diambil. Diantaranya adalah dari segi biaya, jelas lebih murah dari tarif telepon tradisional, karena jaringan IP bersifat global sehingga untuk hubungan Internasional dapat ditekan hingga 70%. Selain itu, biaya maintenance dapat di tekan karena voice dan data network terpisah, sehingga IP Phone dapat ditambah, dipindah dan di ubah. Hal ini karena VoIP dapat dipasang di sembarang ethernet dan IP address, tidak seperti telepon tradisional yang harus mempunyai port tersendiri di Sentral atau PBX.

1.3 KELEMAHAN VOIP Sulit mengirimkan fax Perlu jalur internet yang cepat, biasanya backbone diharuskan menggunakan Fiber optic Susah untuk menentukan emergency call. Kelemahan jaringan yang menjadi musuh VoIP : 1. Delay Jaringan yang berbasis atau dengan backbone Satellite tidak cocok untuk VoIP. Karena delay satellite yang sangat besar. Sehingga menyebabkan suara kita lama didengar oleh lawan bicara. Solusi : Backbone fiber optic. 2. Jitter Jitter pada intinya adalah variasi dalam delay, terjadi karena adanya perubahan terhadap karakteristik dari suatu sinyal sehingga menyebabkan terjadinya masalah terhadap data yang dibawa oleh sinyal tersebut. Solusinya : Mengaplikasikan suatu sistem buffer pada pesawat penerima untuk menstabilkan data suara sebelum ditampilkan. Efek sampingnya akan ada sedikit delay. 3. Packet Loss Paket loss artinya hilangnya paket data yang sedang dikirimkan. Hilangnya data ini bisa disebabkan karena Jitter atau karena adanya permasalahan di perangkat-perangakat jaringan seperti router yang terlalu sibuk, jalur komunikasi yang terlalu padat penggunanya. Solusi : Peralatan yang lebih bagus dibandingkan peralatan jaringan untuk internet biasa, kualitas koneksi yang lebih baik dan perhitungan terhadap penggunaan bandwidth yang lebih baik. 4. Keamanan Karena suara berjalan pada jaringan internet maka tetap akan ada kemungkinan data suara tersebut disadap oleh pihak-pihak yang tidak bertanggung jawab. Solusi : Membangun sistem keamanan yang lebih baik, enkripsi data. 5. Echo Echo atau gema disebabkan oleh kesalahan perangkat pengirim dan penerima suara dalam mengconversikan atau mengubah data dari suara menjadi digital atau sebaliknya biasanya karena adanya kesalahan faktor impedansi dalam rangkaian analog peralatan. Solusi : Melengkapi peralatan dengan rangkaian analog coupling yang bisa meredam kesalahan faktor impedansi.

1.4 CARA KERJA VOIP Hal yang menarik tentang VoIP adalah banyaknya cara untuk melakukan panggilan. Saat ini ada 3 jenis metode yg berbeda yang paling sering digunakan untuk melakukan layalan VoIP, yaitu : 1. ATA (Analog Telephone Adaptor) Cara yang paling sederhana dan paling umum adalah dengan menggunakan suatu alat yang disebut ATA. ATA memungkinkan kita untuk menghubungkan pesawat telepon biasa ke komputer atau disambungkan ke internet untuk dipakai VoIP. ATA adalah alat pengubah sinyal dari analog menjadi digital. Cara kerjanya adalah mengubah sinyal analog dari telepon dan mengubahnya menjadi data digital untuk di transmisikan melalui internet. Provider seperti VONAGE dan AT&T Callvantage membuat alat ATA dan memberikannya secara gratis kepada pelanggannya sebagai bagian dari service mereka. Mereka tinggal membuka ATA, memasang kabel telepon ke alat, dan VoIP sudah bisa digunakan. Beberapa jenis ATA dipaket dan dibundel beserta software tambahan yang harus diinstalkan pada komputer untuk melakukan konfigurasi ATA, tetapi pada umumnya itu hanya setting yang sangat gampang. 2. IP Phones Pesawat telepon khusus ini kelihatannya sama dengan telepon biasa. Tapi selain mempunyai konektor RJ-11 standar, IP Phones juga mempunyai konektor RJ-45. IP Phones menghubungkan langsung dari telepon ke router, dan didalam IP Phones sudah ada semua perangkat keras maupun lunak yang sudah terpasang didalamnya yang menunjang melakukan pemanggilan IP. Tidak lama lagi, IP Phone nirkabel (wireless) akan tersedia, dan memungkinkan para pengguna untuk melakukan panggilan VoIP dari hotspot yang tersedia. 3. Computer-to-Computer Cara ini jelas merupakan cara paling mudah untuk melakukan panggilan VoIP. Anda bahkan tidak usah membayar satu sen pun untuk melakukan panggilan SLJJ. Ada beberapa perusahaan yang menawarkan program yang harganya murah bahkan gratis yang dapat digunakan untuk melakukan panggilan VoIP. Yang harus anda sediakan hanya program (software), mikrofon, speaker, soundcard dan koneksi internet, lebih diutamakan koneksi internet yang relatif cepat seperti koneksi Kabel atau DSL. Selain biaya bulanan ISP, biasanya tidak ada lagi biaya untuk panggilan Computer-to-Computer, seberapa jauh pun jaraknya.

1.5 Protokol Penunjang Jaringan VoIP Ada beberapa protokol yang menjadi penunjang jaringan VoIP, antara lain : 1. Protokol TCP/IPTCP/IP (Transfer Control Protocol/Internet Protocol) merupakan sebuah protokol yang digunakan pada jaringan Internet. Protokol ini terdiri dari dua bagian besar, yaitu TCP dan IP. 2. Application layer Fungsi utama lapisan ini adalah pemindahan file. Perpindahan file dari sebuah sistem ke sistem lainnya yang berbeda memerlukan suatu sistem pengendalian untuk menangatasi adanya ketidak cocokan sistem file yang berbeda beda. Protokol ini berhubungan dengan aplikasi. Salah satu contoh aplikasi yang telah dikenal misalnya HTTP (Hypertext Transfer Protocol) untuk web, FTP(File Transfer Protocol) untuk perpindahan file, dan TELNET untuk terminal maya jarak jauh. 3. TCP (Transmission Control Protocol) Dalam mentransmisikan data pada layer Transpor ada dua protokol yang berperan yaitu TCP danUDP. TCP merupakan protokol yang connection-oriented yang artinya menjaga reliabilitas hubungan komunikadasi end-to-end. Konsep dasar cara kerja TCP adalah mengirm dan menerima segmen segmen informasi dengan panjang data bervariasi pada suatu datagram internet. TCP menjamin realibilitas hubungan komunikasi karena melakukan perbaikan terhadap data yang rusak, hilang atau kesalahan kirim. Hal ini dilakukan dengan memberikan nomor urut pada setiap paket yang dikirimkan dan membutuhkan sinyal jawaban positif dari penerima berupa sinyal ACK(acknoledgment). Jika sinyal ACK ini tidak diterima pada interval pada waktu tertentu, maka data akan dikirikmkan kembali. Pada sisi penerima, nomor urut tadi berguna untuk mencegah kesalahan urutan data dan duplikasi data. TCP juga memiliki mekanisme fllow control dengan cara mencantumkan informasi dalam sinyal ACK mengenai batas jumlah paket data yang masih boleh ditransmisikan pada setiap segmen yang diterima dengan sukses. Dalam hubungan VoIP, TCP digunakan pada saat signaling, TCP digunakan untuk menjamin setup suatu call pada sesi signaling. TCP tidak digunakan dalam pengiriman data suara pada VoIP karena pada suatu komunikasi data VoIP penanganan data yang mengalami keterlambatan lebih penting daripada penanganan paket yang hilang. 4. User Datagram Protocol (UDP) UDP yang merupakan salah satu protocol utama diatas IP merupakan transport protocol yang lebih sederhana dibandingkan dengan TCP. UDP digunakan untuk situasi yang tidak mementingkan mekanisme reliabilitas. Header UDP hanya berisi empat field yaitu source port, destination port, length dan UDP checksum dimana fungsinya hampir
5

sama dengan TCP, namun fasilitas checksumpada UDP bersifat opsional.UDP pada VoIP digunakan untuk mengirimkan audio stream yang dikrimkan secara terus menerus.UDP digunakan pada VoIP karena pada pengiriman audio streaming yang berlangsung terusmenerus lebih mementingkan kecepatan pengiriman data agar tiba di tujuan tanpa memperhatikan adanya paket yang hilang walaupun mencapai 50% dari jumlah paket yang dikirimkan. (VoIP fundamental, Davidson Peters, Cisco System,163 ) Karena UDP mampu mengirimkan data streaming dengan cepat, maka dalam teknologi VoIP UDPmerupakan salah satu protokol penting yang digunakan sebagai header pada pengiriman data selainRTP dan IP. Untuk mengurangi jumlah paket yang hilang saat pengiriman data (karena tidakterdapat mekanisme pengiriman ulang) maka pada teknolgi VoIP pengiriman data banyak dilakukan pada private network. 5. Internet Protocol (IP) Internet Protocol didesain untuk interkoneksi sistem komunikasi komputer pada jaringan paket switched.Pada jaringan TCP/IP, sebuah komputer diidentifikasi dengan alamat IP. Tiap-tiapkomputer memiliki alamat IP yang unik, masing-masing berbeda satu sama lainnya. Hal ini dilakukan untuk mencegah kesalahan pada transfer data. Terakhir, protokol data akses berhubungan langsung dengan media fisik. Secara umum protokol ini bertugas untuk menangani pendeteksiankesalahan pada saat transfer data. Untuk komunikasi datanya, Internet Protokol mengimplementasikan dua fungsi dasar yaitu addressing dan fragmentasi. Salah satu hal penting dalam IP dalam pengiriman informasi adalah metode pengalamatan pengirimdan penerima. Saat ini terdapat standar pengalamatan yang sudah digunakan yaitu IPv4 denganalamat terdiri dari 32 bit. Jumlah alamat yang diciptakan dengan IPv4 diperkirakan tidak dapatmencukupi kebutuhan pengalamatan IP sehingga dalam beberapa tahun mendatang akan diimplementasikan sistim pengalamatan yang baru yaitu IPv6 yang menggunakan sistim pengalamatan 128 bit.

1.6 REGULASI VoIP berkembang karena adanya persaingan yang bebas dan dukungan pemerintah, setidaknya inilah yang terjadi di Amerika. Monopoli perusahaan besar dihindari (misalnya monopoli AT&T diakhiri pada tahun 1984) dan pengawasan ketat pada persaingan yang sehat (misalnya saat dua internet backbone service provider terbesar, MCI dan WorldCom merger pada tahun 1998, pemerintah tetap berusaha agar tidak ada perusahaan yang mendominasi dengan mewajibkan internet backbone mereka dipakai oleh perusahaan kompetitor).
6

Persaingan menyebabkan setiap perusahaan berusaha menghasilkan inovasi/produk baru. Karena adanya resiko investasi, pemerintah AS turut membantu dengan mengurangi pajak guna membantu inovasi dan memacu potensial market dengan mensupport perusahaan pengembang teknologi (The National Institute for Standards and Technology, National Institues of Health, National Oceanic and Atmospheric Administration, dan the National Science Foundation). FCC sebagai salah satu lembaga yang berkompeten mengusulkan traditional charge pada layanan yang secara langsung bersaing dengan traditional company. FCC membedakan layanan voice melalui komputer (enhanced service yang dianggap tidak masuk dalam access charges dan regulasi lain) atau voice melalui handset telpon standar yang mendial melalui gateway IP (dianggap sebagai telepone tradisional dengan long-distance access charges). Perkembangan VoIP dipengaruhi faktor ekonomi, regulasi dan teknologi. Regulasi pemerintah sering sekali menjadi interferensi. Pemerintah mencoba me-micromanage kompetisi yang semakin besar dan terlalu kompleks dengan powerfull financial interest. Sementara industri telkom semakin less regulated dan persaingan semakin bebas. Birokrasi, kecemasan dan social justice dianggap sebagai faktor yang memperlambat proses. Di Indonesia, Pemerintah (dalam hal ini Dirjen Postel) menganggap penyelenggara VOIP mengganggu operator resmi. Pelarangan dilakukan dengan cara penggerebekan meskipun dasar hukumnya tidak kuat. Alasan pelarangan hanya menyangkut soal izin serta tidak adanya standarisasi penggunaan peralatan yang harus dikeluarkan Dirjen Postel. Di sisi lain, sanksi yang dikenakan juga masih terlalu ringan dibanding keuntungan yang diperoleh. Menurut Ir. Suryatin Setiawan Direktur divisi Penelitian dan Pengembangan PT Telkom, VoIP baru bermasalah jika perusahaan penyedianya sudah bertindak sebagai operator. Suhono Supangat, Multimedia Signal Processing and Communication Research Group ITB menjelaskan bahwa pelarangan VoIP tanpa cyberlaw akan membatasi pengembangan aplikasi berbasis IP pada public network.serta menghambat pembuatan jaringan baru yang mendukung beragam komunikasi multimedia yang merupakan basis teknologi massa depan. Indosat juga mempertimbangkan VoIP untuk SLInya, namun terikat ketentuan dalam KM 37/1999 yakni Indosat harus membayar biaya interkoneksi kepada PT Telkom Rp 1.350/menit atau sama dengan US$ 15,5 sen. Peralihan ke teknologi VoIP tidak akan efektif kecuali ketentuan tersebut diubah.

INSTALASI VOIP SERVER UNILA

2.1 Instalasi

Lakukan Instalasi Terlebih System Operasi TRIXBOX terlebih dahulu Instalasi dilakukan sama dengan Instalasi pada System Operasi Linux Lainnya. Hardisk akan ter-format otomatis oleh Linux TRIXBOX ini

Catatan : Backup data anda sebelum instalasi dilakukan

2.2 Konfigurasi IP TRIXBOX Setelah Instalasi, Anda harus mengkonfigurasi IP Address dengan cara : Ketik netconfig Pilih Yes Isi IP Address, Netmask, Default Gateway (IP) dan Primary Name server Pilih OK Kemudian Ketik /etc/init.d/network restart dan enter untuk me-restart network

2.3 Konfigurasi TRIXBOX

Masuk ke Internet Explorer / Web Browser lainnya Ketik IP Address atau hostname TRIXBOX (http://voip.unila.ac.id)

Tampilan Awal Konfigurasi TRIXBOX

10

Klik System Administration Untuk masuk ke menu System administration

Isi user dengan maint Isi Password dengan wuelektro Klik OK untuk melanjutkan

11

2.4 Menu System Administration

Klik Menu FreePBX untuk masuk ke Menu FreePBX

12

Klik Menu Tools Pertama kali kita harus melakukan instalasi module: Core

13

2.5 Menu Tools

Klik Module Admin

14

Beri Tanda centang pada Core (core) Pilih Enable Selected dan kemudian Submit

Klik Menu Setup

15

2.6 Menu Setup

Klik Menu Extensions

Pada Menu Add an Extensions Klik Menu SIP

16

Menu Add SIP Extensions

Isi Extensions Number : Misal 101 Isi Display Name : Misal line1 Isi Secret : Misal 123456 Kemudian Klik Submit Add SIP Extensions digunakan untuk membuat/menambahkan Client. Extensions = User/No VoIP secret = Password

17

Klik You have made changes-when finished, click here to APPLY them Untuk menyimpan hasil perubahan.

18

2.7 Peering ke voiprakyat.or.id Klik Menu Trunks

Klik Menu Add SIP Trunk

Trunk Name : Isikan voiprakyat.or.id Host = Voiprakyat.or.id username = voiprakyat.or.id Secret= Password Register String : (Username : password@voiprakyat.or.id) Klik Submit Changes untuk menyelesaikan konfigurasi

19

Klik You have made changes-when finished, click here to APPLY them Untuk menyimpan hasil perubahan.

Klik Outbound Routes

Route Name: Isikan voiprakyat.or.id Dial Patterns Isi misal 6|x. Trunk Squence Pilih SIP/voiprakyat.or.id Klik Add untuk menambahkan Outbound Routes

20

Klik You have made changes-when finished, click here to APPLY them Untuk menyimpan hasil perubahan.

KETERANGAN

Extensions Merupakan data account extensions (atau client) Trunks Merupakan data account trunks (atau server lain) Outbound Routes Merupakan aturan dial yang akan dimanfaatkan oleh extensions untuk menghubungi trunks

21

2.8 Konfigurasi interkoneksi VOIP server dengan PABX Siemens UNILA.

1. Matikan Power server, pasang card Digium AX-100p 1 FXO pada slot PCI.

2. Masuk ke console CLI TRIXBOX [ root@voip.unila ~]# genzaptelconf TRIXBOX akan secara otomatis mengenali dan menginstall driver AX-100p status pada monitor akan menampilkan warning berikut

Loading wcfxo: wcfxo: DAA mode is FCC Found a Wildcard FXO: Wildcard X100P.

Yang menandakan bahwa Voip server telah berhasil mengenali hardware.

3. check AX-100p status dengan mengetikkan command line utility zttool.* [ root@voip.unila ~]# zttool

commanf Genzaptelconf juga otomatis mengupdate file zapata-auto.conf, file tersebut ada di direktori /etc/asterisk

22

berikut isi file zapata-auto.conf ; Span 1: WCFXO/0 "Wildcard X100P Board 1" RED signalling=fxs_ks ; Note: this is a trunk. Create a ZAP trunk in AMP for Channel 1 context=from-pstn group=0 channel => 1

4. Edit file zapata.conf, dan tambahkan statemen berikut. echocancel=yes echocancelwhenbridged=yes echotraining=yes

5. KOnfigurasi Outbound call trunk dengan memodifikasi default trunk ZAP/g0

Masuk ke menu Trixbox - FreePBX - Trunk Masukkan nomer PSTN/PABX pada outbound caller ID (Ekstensi PABX yang akan digunakan adalah 128) Set Maximum Channels dengan nilai 1. Set Outbound Dial Prefix dengan nilai 9

23

Selanjutnya ubah file /etc/zaptel.conf dengan isian sbb,

loadzone = uk defaultzone = uk

Updating Server Linux, masuk ke direktori /usr/src

> cd /usr/src Download last CVS release dari Zapata driver, asterisk package > export CVSROOT=:pserver: anoncvs@cvs.digium.com:/usr/cvsroot > cvs login (password is anoncvs) > cvs checkout zaptel asterisk

Compile semua packages: zaptel yang pertama, selanjutnya asterisk

> cd /usr/src/zaptel; make install > cd ../asterisk; make install > make samples

24

edit beberapa file config berikut

/etc/zaptel.conf fxsks=1 ;AX-100P defaultzone=uk loadzone=uk

/etc/asterisk/zapata.conf [channels] signalling=fxs_ks context=incoming channel=>1 ; AX-100P

/etc/asterisk/extensions.conf [incoming] exten => s,1,Echo ;for testing the connection ;exten => s,1,Playback,demo-thanks ;for playing a file

Untuk mengaktifkan modul yang sudah diinstall, ketikkan command berikut

> modprobe zaptel > modprobe wcfxo > ztcfg -vv

25

Proses instalasi interkoneksi dari VOIP server ke PABX analog telah selesai ketik command berikut untuk melihat aktifitas di server VOIP

> asterisk -vvvc

Pengujian dilakukan dengan menekan tombol 9 diikuti ekstensi dari PABX UNILA

26

2.9 Petunjuk penggunaan Softphone Client (X-lite 3.0).

Download XLite 3.0 untuk aplikasi telepon VoIP. Pada menu download XLite for free!, klik XLite 3.0 for windows, jika anda menggunakan sistem operasi windows.

27

28

29

30

31

32

33

34

35

2.10 Lampiran File konfigurasi;

Asterisk.conf [directories] astetcdir => /etc/asterisk astmoddir => /usr/lib/asterisk/modules astvarlibdir => /var/lib/asterisk astagidir => /var/lib/asterisk/agi-bin astspooldir => /var/spool/asterisk astrundir => /var/run/asterisk astlogdir => /var/log/asterisk [options] transmit_silence_during_record = yes ; nocolor = yes

cdr_mysql.conf

; ; Note - if the database server is hosted on the same machine as the ; asterisk server, you can achieve a local Unix socket connection by ; setting hostname=localhost ; ; port and sock are both optional parameters. If hostname is specified ; and is not "localhost", then cdr_mysql will attempt to connect to the ; port specified or use the default port. If hostname is not specified ; or if hostname is "localhost", then cdr_mysql will attempt to connect ; to the socket file specified by sock or otherwise use the default socket ; file. ; [global] hostname=localhost dbname=asteriskcdrdb password=amp109 user=asteriskuser ;port=3306 ;sock=/tmp/mysql.sock

36

codec.conf [speex] ; CBR encoding quality [0..10] ; used only when vbr = false quality => 3 ; codec complexity [0..10] ; tradeoff between cpu/quality complexity => 2 ; perceptual enhancement [true / false] ; improves clarity of decoded speech enhancement => true ; voice activity detection [true / false] ; reduces bitrate when no voice detected, used only for CBR (implicit in VBR/ABR) vad => true ; variable bit rate [true / false] ; uses bit rate proportionate to voice complexity vbr => true ; available bit rate [bps, 0 = off] ; encoding quality modulated to match this target bit rate ; not recommended with dtx or pp_vad - may cause bandwidth spikes abr => 0

37

; VBR encoding quality [0-10] ; floating-point values allowed vbr_quality => 4 ; discontinuous transmission [true / false] ; stops transmitting completely when silence is detected ; pp_vad is far more effective but more CPU intensive dtx => false ; preprocessor configuration ; these options only affect Speex v1.1.8 or newer ; enable preprocessor [true / false] ; allows dsp functionality below but incurs CPU overhead preprocess => false ; preproc voice activity detection [true / false] ; more advanced equivalent of DTX, based on voice frequencies pp_vad => false ; preproc automatic gain control [true / false] pp_agc => false pp_agc_level => 8000 ; preproc denoiser [true / false] pp_denoise => false ; preproc dereverb [true / false] pp_dereverb => false pp_dereverb_decay => 0.4 pp_dereverb_level => 0.3

38

[plc] ; for all codecs which do not support native PLC ; this determines whether to perform generic PLC ; there is a minor performance penalty for this genericplc => true

extconfig.conf ; ; Static and realtime external configuration ; engine configuration ; ; Please read doc/README.extconfig for basic table ; formatting information. ; [settings] ; ; Static configuration files: ; ; file.conf => driver,database[,table] ; ; maps a particular configuration file to the given ; database driver, database and table (or uses the ; name of the file as the table if not specified) ; ;uncomment to load queues.conf via the odbc engine. ; ;queues.conf => odbc,asterisk,ast_config ; ; The following files CANNOT be loaded from Realtime storage: ; asterisk.conf ; extconfig.conf (this file) ; logger.conf ; ; Additionally, the following files cannot be loaded from

39

; Realtime storage unless the storage driver is loaded ; early using 'preload' statements in modules.conf: ; manager.conf ; cdr.conf ; rtp.conf ; ; ; Realtime configuration engine ; ; maps a particular family of realtime ; configuration to a given database driver, ; database and table (or uses the name of ; the family if the table is not specified ; ;example => odbc,asterisk,alttable ;iaxusers => odbc,asterisk ;iaxpeers => mysql,asteriskrealtime,iax_buddies ;sipusers => odbc,asterisk ;sippeers => mysql,asteriskrealtime,sip_buddies ;voicemail => mysql,asteriskrealtime,voicemail_users ;extensions => mysql,asteriskrealtime,extensions ;queues => odbc,asterisk ;queue_members => odbc,asterisk

extension.conf ; FreePBX ; Copyright (C) 2004 Coalescent Systems Inc (Canada) ; Copyright (C) 2006 Why Pay More 4 Less Pty Ltd (Australia) ; Released under the GNU GPL Licence version 2. ; dialparties.agi (http://www.sprackett.com/asterisk/) ; Asterisk::AGI (http://asterisk.gnuinter.net/) ; gsm (http://www.ibiblio.org/pub/Linux/utils/compress/!INDEX.short.ht ml) ; loligo sounds (http://www.loligo.com/asterisk/sounds/) ; mpg123 (http://voip-info.org/wikiAsterisk+config+musiconhold.conf)

40

; include extension contexts generated from AMP #include extensions_additional.conf ; Customizations to this dialplan should be made in extensions_custom.conf ; See extensions_custom.conf.sample for an example #include extensions_custom.conf [from-trunk] since VoIP shouldn't be called PSTN include => from-pstn ; just an alias

[from-pstn] include => from-pstn-custom ; create this context in extensions_custom.conf to include customizations include => ext-did-direct ; MODIFICATOIN (PL) put before ext-did to take precedence include => ext-did include => from-did-direct ; MODIFICATOIN (PL) for findmefollow if enabled, should be bofore ext-local exten => fax,1,Goto(ext-fax,in_fax,1) ; MODIFICATION (PL) ; ; Required to assure that direct dids go to personal ring group before local extension. ; This could be auto-generated however I it is prefered to be put here and hard coded ; so that it can be modified if ext-local should take precedence in certain situations. ; will have to decide what to do later. ; [from-did-direct] include => ext-findmefollow include => ext-local

41

; ######################################################### ################### ; Macros [macro] ; ######################################################### ################### ; Rings one or more extensions. Handles things like call forwarding and DND ; We don't call dial directly for anything internal anymore. ; ARGS: $TIMER, $OPTIONS, $EXT1, $EXT2, $EXT3, ... ; Use a Macro call such as the following: ; Macro(dial,$DIAL_TIMER,$DIAL_OPTIONS,$EXT1,$EXT2,$EXT3,...) [macro-dial] exten => s,1,DeadAGI(dialparties.agi) exten => s,2,NoOp(Returned from dialparties with no extensions to call) exten => s,3,NoOp(DIALSTATUS is '${DIALSTATUS}') exten => s,10,Dial(${ds}) priority to 10 if $ds is not null ; dialparties will set the

exten => s,20,NoOp(Returned from dialparties with hunt groups to dial ) exten => s,21,Set(HuntLoop=0) exten => s,22,GotoIf($[${HuntMembers} >= 1]?30 ) ; if this is from rggroup, don't strip prefix exten => s,23,NoOp(Returning there are no members left in the hunt group to ring) exten => s,30,Set(HuntMember=HuntMember${HuntLoop}) exten => s,31,GotoIf($[$["${CALLTRACE_HUNT}" != "" ] & $["${RingGroupMethod}" = "hunt" ]]?32:35 ) ; Set CAll Trace for Hunt member we are going to call exten => s,32,Set(CT_EXTEN=${CUT(ARG3,,$[${HuntLoop} + 1])}) exten => s,33,Set(DB(CALLTRACE/${CT_EXTEN})=${CALLTRACE_HUNT}) exten => s,34,Goto(s,42)

42

exten => s,35,GotoIf($[$["${CALLTRACE_HUNT}" != "" ] & $["${RingGroupMethod}" = "memoryhunt" ]]?36:50 ) ;Set Call Trace for each hunt member we are going to call "Memory groups have multiple members to set CALL TRACE For hence the loop exten => s,36,Set(CTLoop=0) exten => s,37,GotoIf($[${CTLoop} > ${HuntLoop}]?42 ) ; if this is from rg-group, don't strip prefix exten => s,38,Set(CT_EXTEN=${CUT(ARG3,,$[${CTLoop} + 1])}) exten => s,39,Set(DB(CALLTRACE/${CT_EXTEN})=${CALLTRACE_HUNT}) exten => s,40,Set(CTLoop=$[1 + ${CTLoop}]) exten => s,41,Goto(s,37) exten => s,42,Dial(${${HuntMember}}${ds} ) ; dialparties will set the priority to 20 if $ds is not null and its a hunt group exten => s,43,Set(HuntLoop=$[1 + ${HuntLoop}]) exten => s,44,Set(HuntMembers=$[${HuntMembers} - 1]) exten => s,45,Goto(s,22) exten => s,50,DBdel(CALLTRACE/${CT_EXTEN}) exten => s,51,Goto(s,42) ; make sure hungup calls go here so that proper cleanup occurs from call confirmed calls and the like ; exten => h,1,Macro(hangupcall) ; Ring an extension, if the extension is busy or there is no answer send it ; to voicemail ; ARGS: $VMBOX, $EXT [macro-exten-vm] exten => s,1,Macro(user-callerid) exten => s,n,Set(FROMCONTEXT=exten-vm) exten => s,n,Set(VMBOX=${ARG1}) exten => s,n,Set(EXTTOCALL=${ARG2}) exten => s,n,Set(CFUEXT=${DB(CFU/${EXTTOCALL})}) exten => s,n,Set(CFBEXT=${DB(CFB/${EXTTOCALL})}) exten => s,n,Set(RT=${IF($[$["${VMBOX}"!="novm"] | $["foo${CFUEXT}"!="foo"]]?${RINGTIMER}:"")})
43

exten => s,n,Macro(record-enable,${EXTTOCALL},IN) exten => s,n,Macro(dial,${RT},${DIAL_OPTIONS},${EXTTOCALL}) exten => s,n,GosubIf($[$["${DIALSTATUS}"="NOANSWER"] & $["foo${CFUEXT}"!="foo"]]?docfu,1) ; check for CFU in use on no answer exten => s,n,GosubIf($[$["${DIALSTATUS}"="BUSY"] & $["foo${CFBEXT}"!="foo"]]?docfb,1) ; check for CFB in use on busy exten => s,n,NoOp(Voicemail is '${VMBOX}') exten => s,n,GotoIf($["${VMBOX}" = "novm"]?s-${DIALSTATUS},1) ; no voicemail in use for this extension exten => s,n,NoOp(Sending to Voicemail box ${EXTTOCALL}) exten => s,n,Macro(vm,${VMBOX},${DIALSTATUS}) ; Try the Call Forward on No Answer / Unavailable number exten => docfu,1,Set(RTCFU=${IF($["${VMBOX}"!="novm"]?${RINGTIMER}:"")}) exten => docfu,n,Dial(Local/${CFUEXT}@frominternal/n,${RTCFU},${DIAL_OPTIONS}) exten => docfu,n,Return ; Try the Call Forward on Busy number exten => docfb,1,Set(RTCFB=${IF($["${VMBOX}"!="novm"]?${RINGTIMER}:"")}) exten => docfb,n,Dial(Local/${CFBEXT}@frominternal/n,${RTCFB},${DIAL_OPTIONS}) exten => docfb,n,Return ; Extensions with no Voicemail box reporting BUSY come here exten => s-BUSY,1,NoOp(Extension is reporting BUSY and not passing to Voicemail) exten => s-BUSY,n,Playtones(busy) exten => s-BUSY,n,Busy(20) ; Anything but BUSY comes here exten => _s-.,1,Playtones(congestion) exten => _s-.,n,Congestion(10) [macro-vm] exten => s,1,Macro(user-callerid,SKIPTTL)
44

exten => s,n,Set(VMGAIN=${IF($["foo${VM_GAIN}"!="foo"]?"g(${VM_GAIN})":"")}) ; ; If BLKVM_OVERRIDE is set, then someone told us to block calls from going to ; voicemail. This variable is reset by the answering channel so subsequent ; transfers will properly function. ; exten => s,n,GotoIf($["foo${DB(${BLKVM_OVERRIDE})}" != "fooTRUE"]?s-${ARG2},1) ; ; we didn't branch so block this from voicemail ; exten => s,n,Noop(CAME FROM: ${NODEST} - Blocking VM cause of key: ${DB(BLKVM_OVERRIDE)}) exten => s-BUSY,1,NoOp(BUSY voicemail) exten => s-BUSY,n,Macro(get-vmcontext,${ARG1}) exten => sBUSY,n,Voicemail(${ARG1}@${VMCONTEXT}|${VM_OPTS}b${VMGAIN} ) ; Voicemail Busy message exten => s-BUSY,n,Goto(exit-${VMSTATUS},1) exten => s-DIRECTDIAL,1,NoOp(DIRECTDIAL voicemail) exten => s-DIRECTDIAL,n,Macro(get-vmcontext,${ARG1}) exten => sDIRECTDIAL,n,Voicemail(${ARG1}@${VMCONTEXT}|${VM_OPTS}${VM _DDTYPE}${VMGAIN}) exten => s-DIRECTDIAL,n,Goto(exit-${VMSTATUS},1) exten => _s-.,1,Macro(get-vmcontext,${ARG1}) exten => _s.,n,Voicemail(${ARG1}@${VMCONTEXT}|${VM_OPTS}u${VMGAIN}) Voicemail Unavailable message exten => _s-.,n,Goto(exit-${VMSTATUS},1) exten => o,1,Background(one-moment-please) message will hangup ; 0 during vm

45

exten => o,n,GotoIf($["x${OPERATOR_XTN}"="x"]?nooper:frominternal,${OPERATOR_XTN},1) exten => o,n(nooper),GotoIf($["x${FROM_DID}"="x"]?nodid) exten => o,n,Dial(Local/${FROM_DID}@from-pstn) exten => o,n,Macro(hangup) exten => o,n(nodid),Dial(Local/s@from-pstn) exten => o,n,Macro(hangup) exten => a,1,Macro(get-vmcontext,${ARG1}) exten => a,n,VoiceMailMain(${ARG1}@${VMCONTEXT}) exten => a,n,Hangup exten => exit-FAILED,1,Playback(im-sorry&an-error-has-occured) exten => exit-FAILED,n,Hangup() exten => exit-SUCCESS,1,Playback(goodbye) exten => exit-SUCCESS,n,Hangup() exten => exit-USEREXIT,1,Playback(goodbye) exten => exit-USEREXIT,n,Hangup() exten => t,1,Hangup() ;-----------------------------------------------------------------------; [macro-simple-dial] ;-----------------------------------------------------------------------; This macro was derived from macro-exten-vm, which is what is normally used to ; ring an extension. It has been simplified and designed to never go to voicemail ; and always return regardless of the DIALSTATUS for any incomplete call. ; ; It's current primary purpose is to allow findmefollow ring an extension prior ; to trying the follow-me ringgroup that is provided. ; ; Ring an extension, if the extension is busy or there is no answer, return ; ARGS: $EXTENSION, $RINGTIME
46

;-----------------------------------------------------------------------[macro-simple-dial] exten => s,1,Macro(user-callerid,SKIPTTL) ; already called from followme ; FROMCONTEXT was in the original macro-exten-vm where this macro was derived from. A ; search through all the modules does not come up with any place using this ; variable, but it is left here as a reminder in case there is functionality ; that eventually behaves in a certain way as a result of this variable being set ; and this macro has to masquerade as exten-vm. ; exten => s,n,Set(EXTTOCALL=${ARG1}) exten => s,n,Set(RT=${ARG2}) exten => s,n,Set(CFUEXT=${DB(CFU/${EXTTOCALL})}) exten => s,n,Set(CFBEXT=${DB(CFB/${EXTTOCALL})}) exten => s,n,Macro(record-enable,${EXTTOCALL},IN) exten => s,n,Macro(dial,${RT},${DIAL_OPTIONS},${EXTTOCALL}) exten => s,n,Set(PR_DIALSTATUS=${DIALSTATUS}) ; if we return, thus no answer, and they have a CFU setting, then we try that next ; exten => s,n,GosubIf($[$["${DIALSTATUS}"="NOANSWER"] & $["foo${CFUEXT}"!="foo"]]?docfu,1) ; check for CFU in use on no answer exten => s,n,GosubIf($[$["${DIALSTATUS}"="BUSY"] & $["foo${CFBEXT}"!="foo"]]?docfb,1) ; check for CFB in use on busy ; Nothing yet, then go to the end (which will just return, but in case we decide to do something with certain ; return situations, this is left in. ; exten => s,n,Goto(s-${DIALSTATUS},1)

47

; Try the Call Forward on No Answer / Unavailable number. ; We want to try CFU if set, but we want the same ring timer as was set to our call (or do we want the ; system ringtimer? - probably not). Then if no answer there (assuming it doesn't drop into their vm or ; something we return, which will have the net effect of returning to the followme setup.) ; ; want to avoid going to other follow-me settings here. So check if the CFUEXT is a user and if it is ; then direct it straight to ext-local (to avoid getting intercepted by findmefollow) otherwise send it ; to from-internal since it may be an outside line. ; exten => docfu,1,GotoIf( $[ "foo${DB(AMPUSER/${CFUEXT}/device)}" = "foo" ]?chlocal) exten => docfu,n,Dial(Local/${CFUEXT}@extlocal,${RT},${DIAL_OPTIONS}) exten => docfu,n,Return exten => docfu,n(chlocal),Dial(Local/${CFUEXT}@frominternal/n,${RT},${DIAL_OPTIONS}) exten => docfu,n,Return ; Try the Call Forward on Busy number exten => docfb,1,GotoIf( $[ "foo${DB(AMPUSER/${CFBEXT}/device)}" = "foo" ]?chlocal) exten => docfb,n,Dial(Local/${CFBEXT}@extlocal,${RT},${DIAL_OPTIONS}) exten => docfb,n,Return exten => docfb,n(chlocal),Dial(Local/${CFBEXT}@frominternal/n,${RT},${DIAL_OPTIONS}) exten => docfb,n,Return ; In all cases of no connection, come here and simply return, since the calling dialplan will ; decide what to do next exten => _s-.,1,NoOp(Extension is reporting ${EXTEN}) ;------------------------------------------------------------------------

48

; get the voicemail context for the user in ARG1 [macro-get-vmcontext] exten => s,1,Set(VMCONTEXT=${DB(AMPUSER/${ARG1}/voicemail)}) exten => s,2,GotoIf($["foo${VMCONTEXT}" = "foo"]?200:300) exten => s,200,Set(VMCONTEXT=default) exten => s,300,NoOp() ; For some reason, if I don't run setCIDname, CALLERID(name) will be blank in my AGI ; ARGS: none [macro-fixcid] exten => s,1,Set(CALLERID(name)=${CALLERID(name)}) ; Ring groups of phones ; ARGS: comma separated extension list ; 1 - Ring Group Strategy ; 2 - ringtimer ; 3 - prefix ; 4 - extension list [macro-rg-group] exten => s,1,Macro(user-callerid,SKIPTTL) ; already called from ringgroup exten => s,2,GotoIf($["${CALLERID(name):0:${LEN(${RGPREFIX})}}" != "${RGPREFIX}"]?4:3) ; check for old prefix exten => s,3,Set(CALLERID(name)=${CALLERID(name):${LEN(${RGPREFIX})}}) ; strip off old prefix exten => s,4,Set(RGPREFIX=${ARG3}) ; set new prefix exten => s,5,Set(CALLERID(name)=${RGPREFIX}${CALLERID(name)}) ; add prefix to callerid name exten => s,6,Set(RecordMethod=Group) ; set new prefix exten => s,7,Macro(record-enable,${MACRO_EXTEN},${RecordMethod}) exten => s,8,Set(RingGroupMethod=${ARG1}) ; exten => s,9,Macro(dial,${ARG2},${DIAL_OPTIONS},${ARG4}) exten => s,10,Set(RingGroupMethod='') ;

; ; Outgoing channel(s) are busy ... inform the client

49

; but use noanswer features like ringgroups don't break by being answered ; just to play the message. ; [macro-outisbusy] exten => s,1,Playback(all-circuits-busy-now,noanswer) exten => s,n,Playback(pls-try-call-later,noanswer) exten => s,n,Macro(hangupcall) ; What to do on hangup. [macro-hangupcall] exten => s,1,ResetCDR(w) exten => s,n,NoCDR() ; Cleanup any remaining RG flag ; exten => s,n,GotoIf($[ "foo${USE_CONFIRMATION}" = "foo" | "foo${RINGGROUP_INDEX}" = "foo" | "${CHANNEL}" != "${UNIQCHAN}"]?skiprg) exten => s,n,Noop(Cleaning Up Confirmation Flag: RG/${RINGGROUP_INDEX}/${CHANNEL}) exten => s,n,DBDel(RG/${RINGGROUP_INDEX}/${CHANNEL}) ; Cleanup any remaining BLKVM flag ; exten => s,n(skiprg),GotoIf($[ "foo${BLKVM_BASE}" = "foo" | "BLKVM/${BLKVM_BASE}/${CHANNEL}" != "${BLKVM_OVERRIDE}" ]?theend) exten => s,n,Noop(Cleaning Up Block VM Flag: ${BLKVM_OVERRIDE}) exten => s,n,DBDel(${BLKVM_OVERRIDE}) exten => s,n(theend),Wait(5) exten => s,n,Hangup [macro-faxreceive] exten => s,1,Set(FAXFILE=/var/spool/asterisk/fax/${UNIQUEID}.tif) exten => s,2,Set(EMAILADDR=${FAX_RX_EMAIL}) exten => s,3,rxfax(${FAXFILE}) exten => s,103,Set(EMAILADDR=${FAX_RX_EMAIL}) exten => s,104,Goto(3)
50

; dialout and strip the prefix [macro-dialout] exten => s,1,Macro(user-callerid,SKIPTTL) exten => s,2,GotoIf($["${ECID${CALLERID(number)}}" = ""]?5) ;check for CID override for exten exten => s,3,Set(CALLERID(all)=${ECID${CALLERID(number)}}) exten => s,4,Goto(7) exten => s,5,GotoIf($["${OUTCID_${ARG1}}" = ""]?7) ;check for CID override for trunk exten => s,6,Set(CALLERID(all)=${OUTCID_${ARG1}}) exten => s,7,Set(length=${LEN(${DIAL_OUT_${ARG1}})}) exten => s,8,Dial(${OUT_${ARG1}}/${ARG2:${length}}) exten => s,9,Playtones(congestion) exten => s,10,Congestion(5) exten => s,109,Macro(outisbusy)

; dialout using default OUT trunk - no prefix [macro-dialout-default] exten => s,1,Macro(user-callerid,SKIPTTL) exten => s,2,Macro(record-enable,${CALLERID(number)},OUT) exten => s,3,Macro(outbound-callerid,${ARG1}) exten => s,4,Dial(${OUT}/${ARG1}) exten => s,5,Playtones(congestion) exten => s,6,Congestion(5) exten => s,105,Macro(outisbusy) ; dialout using a trunk, using pattern matching (don't strip any prefix) ; arg1 = trunk number, arg2 = number, arg3 = route password ; ; MODIFIED (PL) ; ; Modified both Dial() commands to include the new TRUNK_OPTIONS from the general ; screen of AMP ; [macro-dialout-trunk] exten => s,1,Set(DIAL_TRUNK=${ARG1})

51

; If NODEST is set, clear it. No point in remembering since dialouttrunk will just end in the ; bit bucket. But if answered by an outside line with transfer capability, we want NODEST to be ; clear so a subsequent transfer to an internal extension works and goes to voicmail or other ; destinations. ; exten => s,n,Set(_NODEST=) exten => s,n,Set(DIAL_NUMBER=${ARG2}) exten => s,n,Set(ROUTE_PASSWD=${ARG3}) exten => s,n,Set(DIAL_TRUNK_OPTIONS=${DIAL_OPTIONS}) // will be reset to TRUNK_OPTIONS if not intra-company exten => s,n,GotoIf($["${ROUTE_PASSWD}" = ""]?noauth) ; arg3 is pattern password exten => s,n(auth),Authenticate(${ROUTE_PASSWD}) exten => s,n(noauth),Set(GROUP()=OUT_${DIAL_TRUNK}) exten => s,n,Macro(user-callerid,SKIPTTL) exten => s,n,Macro(record-enable,${CALLERID(number)},OUT) exten => s,n,GotoIf($["${INTRACOMPANYROUTE}" = "YES"]?skipoutcid) ;Set to YES if treated like internal exten => s,n,Set(DIAL_TRUNK_OPTIONS=${TRUNK_OPTIONS}) exten => s,n,Macro(outbound-callerid,${DIAL_TRUNK}) exten => s,n(skipoutcid),GotoIf($["${OUTMAXCHANS_${DIAL_TRUNK}}foo" = "foo"]?nomax) exten => s,n(checkmax),GotoIf($[ ${GROUP_COUNT()} > ${OUTMAXCHANS_${DIAL_TRUNK}} ]?chanfull) exten => s,n(nomax),DeadAGI(fixlocalprefix) ; this sets DIAL_NUMBER to the proper dial string for this trunk exten => s,n,Set(OUTNUM=${OUTPREFIX_${DIAL_TRUNK}}${DIAL_NUMBER}) ; OUTNUM is the final dial number exten => s,n,Set(custom=${CUT(OUT_${DIAL_TRUNK},:,1)}) ; Custom trunks are prefixed with "AMP:" exten => s,n,GotoIf($["${custom}" = "AMP"]?customtrunk) exten => s,n,Dial(${OUT_${DIAL_TRUNK}}/${OUTNUM},300,${DIAL_TRUNK_OP TIONS}) ; Regular Trunk Dial
52

exten => s,n,Goto(s-${DIALSTATUS},1) exten => s,n(customtrunk),Set(pre_num=${CUT(OUT_${DIAL_TRUNK},$,1)}) exten => s,n,Set(the_num=${CUT(OUT_${DIAL_TRUNK},$,2)}) ; this is where we expect to find string OUTNUM exten => s,n,Set(post_num=${CUT(OUT_${DIAL_TRUNK},$,3)}) exten => s,n,GotoIf($["${the_num}" = "OUTNUM"]?outnum:skipoutnum) ; if we didn't find "OUTNUM", then skip to Dial exten => s,n(outnum),Set(the_num=${OUTNUM}) ; replace "OUTNUM" with the actual number to dial exten => s,n(skipoutnum),Dial(${pre_num:4}${the_num}${post_num},300,${DIA L_TRUNK_OPTIONS}) exten => s,n,Goto(s-${DIALSTATUS},1) exten => s,n(chanfull),Noop(max channels used up) exten => s-BUSY,1,NoOp(Dial failed due to trunk reporting BUSY giving up) exten => s-BUSY,2,Busy(20) exten => s-NOANSWER,1,NoOp(Dial failed due to trunk reporting NOANSWER - giving up) exten => s-NOANSWER,2,Playtones(congestion) exten => s-NOANSWER,3,Congestion(20) exten => s-CANCEL,1,NoOp(Dial failed due to trunk reporting CANCEL - giving up) exten => s-CANCEL,2,Playtones(congestion) exten => s-CANCEL,3,Congestion(20) exten => _s-.,1,NoOp(Dial failed due to ${DIALSTATUS} - failing through to other trunks) exten => h,1,Macro(hangupcall) ; Adds a dynamic agent/member to a Queue ; Prompts for call-back number - in not entered, uses CIDNum [macro-agent-add]
53

exten => s,1,Wait(1) exten => s,2,Macro(user-callerid,SKIPTTL) exten => s,3,Read(CALLBACKNUM,agent-user) ; get callback number from user exten => s,4,GotoIf($["${CALLBACKNUM}" = ""]?5:7) ; if user just pressed # or timed out, use cidnum exten => s,5,Set(CALLBACKNUM=${CALLERID(number)}) exten => s,6,GotoIf($["${CALLBACKNUM}" = ""]?2) ; if still no number, start over exten => s,7,GotoIf($["${ARG2}" = ""]?9:8) ; arg2 is queue password exten => s,8,Authenticate(${ARG2}) exten => s,9,AddQueueMember(${ARG1}|Local/${CALLBACKNUM}@frominternal/n) ; using chan_local allows us to have agents over trunks exten => s,10,UserEvent(Agentlogin|Agent: ${CALLBACKNUM}) exten => s,11,Wait(1) exten => s,12,Playback(agent-loginok) exten => s,13,Hangup() ; Removes a dynamic agent/member from a Queue ; Prompts for call-back number - in not entered, uses CIDNum [macro-agent-del] exten => s,1,Wait(1) exten => s,2,Macro(user-callerid,SKIPTTL) exten => s,3,Read(CALLBACKNUM,agent-user) ; get callback number from user exten => s,4,GotoIf($["${CALLBACKNUM}" = ""]?5:7) ; if user just pressed # or timed out, use cidnum exten => s,5,Set(CALLBACKNUM=${CALLERID(number)}) exten => s,6,GotoIf($["${CALLBACKNUM}" = ""]?2) ; if still no number, start over exten => s,7,RemoveQueueMember(${ARG1}|Local/${CALLBACKNUM}@frominternal/n) exten => s,8,UserEvent(RefreshQueue) exten => s,9,Wait(1) exten => s,10,Playback(agent-loggedoff) exten => s,11,Hangup()
54

; arg1 = trunk number, arg2 = number [macro-dialout-enum] ; This has been violently beaten upon by Rob Thomas, xrobau@gmail.com ; to 1: Be compliant with all the depreciated bits in asterisk 1.2 and ; above, and 2: to give a good shot at attempting to be compliant with ; RFC3761 by honouring the order in which records are returned. exten => s,1,GotoIf($["${ARG3}" != ""]?PASSWD:NOPASSWD); arg3 is pattern password exten => s,n(PASSWD),Authenticate(${ARG3}) exten => s,n(NOPASSWD),Macro(user-callerid,SKIPTTL) exten => s,n,Macro(record-enable,${CALLERID(number)},OUT) exten => s,n,Macro(outbound-callerid,${ARG1}) exten => s,n,Set(GROUP()=OUT_${ARG1}) exten => s,n,GotoIf($[ ${GROUP_COUNT()} > ${OUTMAXCHANS_${ARG1}} ]?nochans) exten => s,n,Set(DIAL_NUMBER=${ARG2}) exten => s,n,Set(DIAL_TRUNK=${ARG1}) exten => s,n,DeadAGI(fixlocalprefix) ; this sets DIAL_NUMBER to the proper dial string for this trunk exten => s,n,Set(E164NETWORKS=e164.arpa-e164.info-e164.org) ; enum networks to check exten => s,n,GotoIf($["${DIAL_NUMBER:0:1}" = "+"]?begin) ; Skip next line if it already is prefixed by a plus exten => s,n,Set(DIAL_NUMBER=+${DIAL_NUMBER}) ; Add a plus to the start, becasue ENUMLOOKUP needs it. ; start of exten => exten => exten => exten => main network loop s,n(begin),NoOp(E164NETWORKS is ${E164NETWORKS}) s,n,GotoIf($["${E164NETWORKS:1:2}"=""]?failedtotally) s,n,Set(ENUMNET=${CUT(E164NETWORKS,-,1)}) s,n,Set(E164NETWORKS=${CUT(E164NETWORKS,-,2-)})

exten => s,n,NoOp(E164NETWORKS is now ${E164NETWORKS}) exten => s,n,NoOp(ENUMNET is ${ENUMNET}) exten => s,n,Set(ENUMCOUNT=${ENUMLOOKUP(${DIAL_NUMBER},all,c,${ENU MNET})})
55

exten => s,n,Set(ENUMPTR=0) exten => s,n,Set(LOOKUPBUG=0) ; start of main lookup loop exten => s,n(startloop),GotoIf($["${ENUMPTR}"<"${ENUMCOUNT}"]?continue:fail ed) ; Now, let's start through them. exten => s,n(continue),Set(ENUMPTR=$[${ENUMPTR}+1]) exten => s,n,NoOp(Doing ENUMLOOKUP(${DIAL_NUMBER},all,${ENUMPTR},${ENUMNET})) exten => s,n,Set(ENUM=${ENUMLOOKUP(${DIAL_NUMBER},all,${ENUMPTR},${ ENUMNET})}) ; Deal with reponse exten => s,n,GotoIf($["${ENUM:0:3}" = "sip" ]?sipuri) exten => s,n,GotoIf($["${ENUM:0:3}" = "iax" ]?iaxuri) ; It doesn't matter if you don't have h323 enabled, as when it tries to dial, it cares ; about dialstatus and retries if there are any enum results left. exten => s,n,GotoIf($["${ENUM:0:3}" = "h32" ]?h323uri) ; e164.org can return 'ADDRESS' lines. Because of *'s poor handling of Enum ; lookups, we want to DECREMENT the enum pointer. Yes. That means we try more ; times than there actually exists entries. exten => s,n,GotoIf($["${ENUM:0:3}" = "ADD" ]?enumbug) ; OK. If we're here, we've still got some enum entries to go through. Back to ; the start with you! exten => s,n,Goto(startloop) ; We're here because of the poor implementation of ENUMLOOKUP in Asterisk. It ; is quite possible to do three ENUMLOOKUPS and get the same entry each time.
56

; The only workaround I can think of is when we hit an invalid entry, do a ; DECREMENT of the pointer, and keep trying. exten => s,n(enumbug),Set(ENUMPTR=$[${ENUMPTR}-1]) exten => s,n,NoOp(If this is looping with the same ENUM value, The ENUMLOOKUP function is fixed!) exten => s,n,Set(LOOKUPBUG=$[${LOOKUPBUG}+1]) ; If we've done this more than, ooh, 5 times, then give up on this network. Sorry. exten => s,n,GotoIf($["${LOOKUPBUG}" > 5 ]?failed) exten => s,n,Goto(continue) ; If the prefix is 'sip:'... exten => s,n(sipuri),Set(DIALSTR=SIP/${ENUM:4}) exten => s,n,Goto(dodial) ; If it's IAX2... exten => s,n(iaxuri),Set(DIALSTR=IAX2/${ENUM:5}) exten => s,n,Goto(dodial) ; Or even if it's H323. exten => s,n(h323uri),Set(DIALSTR=H323/${ENUM:5}) exten => s,n(dodial),Dial(${DIALSTR}) exten => s,n,NoOp(Dial exited in macro-enum-dialout with ${DIALSTATUS}) ; Now, if we're still here, that means the Dial failed for some reason. ; If it's CONGESTION or CHANUNAVAIL we probably want to try again on a ; different channel. However, if it's the last one, we don't have any ; left, and I didn't keep any previous dialstatuses, so hopefully ; someone looking throught the logs would have seen the NoOp's exten => s,n,GotoIf($["${ENUMPTR}"<"${ENUMCOUNT}"]?maybemore:dialfailed) exten => s,n(maybemore),GotoIf($[ $[ "${DIALSTATUS}" = "CHANUNAVAIL" ] | $[ "${DIALSTATUS}" = "CONGESTION" ] ]?continue)

57

; If we're here, then it's BUSY or NOANSWER or something and well, deal with it. exten => s,n(dialfailed),Goto(s-${DIALSTATUS},1) ; Here are the exit points for the macro. exten => s,n(failed),NoOp(EnumLookup failed on network ${ENUMNET}) exten => s,n,Goto(begin) exten => s,n(failedtotally),NoOp(EnumLookup failed -- no more networks to try) exten => s,n,Goto(end) exten => s,n(nochans),NoOp(max channels used up) exten => s,n(end),NoOp(Exiting macro-dialout-enum) exten => s-BUSY,1,NoOp(Trunk is reporting BUSY) exten => s-BUSY,2,Busy(20) exten => _s-.,1,NoOp(Dial failed due to ${DIALSTATUS}) [macro-record-enable] exten => s,1,GotoIf($[${LEN(${BLINDTRANSFER})} > 0]?2:4) exten => s,2,ResetCDR(w) exten => s,3,StopMonitor() ; I haven't figured out how, but occasionally a hung up ; call can end up here. If you don't use DeadAGI (which does ; work fine as a normal AGI), asterisk deadlocks a thread, ; and ends up grumpy. exten => s,4,DeadAGI(recordingcheck,${TIMESTAMP},${UNIQUEID}) exten => s,5,Noop(No recording needed) exten => s,999,MixMonitor(${CALLFILENAME}.wav) ;exten => s,3,BackGround(for-quality-purposes) ;exten => s,4,BackGround(this-call-may-be) ;exten => s,5,BackGround(recorded) ; This macro is for dev purposes and just dumps channel/app variables. Useful when designing new contexts.
58

[macro-dumpvars] exten => s,1,Noop(ACCOUNTCODE=${ACCOUNTCODE}) exten => s,2,Noop(ANSWEREDTIME=${ANSWEREDTIME}) exten => s,3,Noop(BLINDTRANSFER=${BLINDTRANSFER}) exten => s,4,Noop(CALLERID=${CALLERID(all)}) exten => s,5,Noop(CALLERID(name)=${CALLERID(name)}) exten => s,6,Noop(CALLERID(number)=${CALLERID(number)}) exten => s,7,Noop(CALLINGPRES=${CALLINGPRES}) exten => s,8,Noop(CHANNEL=${CHANNEL}) exten => s,9,Noop(CONTEXT=${CONTEXT}) exten => s,10,Noop(DATETIME=${DATETIME}) exten => s,11,Noop(DIALEDPEERNAME=${DIALEDPEERNAME}) exten => s,12,Noop(DIALEDPEERNUMBER=${DIALEDPEERNUMBER}) exten => s,13,Noop(DIALEDTIME=${DIALEDTIME}) exten => s,14,Noop(DIALSTATUS=${DIALSTATUS}) exten => s,15,Noop(DNID=${DNID}) exten => s,16,Noop(EPOCH=${EPOCH}) exten => s,17,Noop(EXTEN=${EXTEN}) exten => s,18,Noop(HANGUPCAUSE=${HANGUPCAUSE}) exten => s,19,Noop(INVALID_EXTEN=${INVALID_EXTEN}) exten => s,20,Noop(LANGUAGE=${LANGUAGE}) exten => s,21,Noop(MEETMESECS=${MEETMESECS}) exten => s,22,Noop(PRIORITY=${PRIORITY}) exten => s,23,Noop(RDNIS=${RDNIS}) exten => s,24,Noop(SIPDOMAIN=${SIPDOMAIN}) exten => s,25,Noop(SIP_CODEC=${SIP_CODEC}) exten => s,26,Noop(SIPCALLID=${SIPCALLID}) exten => s,27,Noop(SIPUSERAGENT=${SIPUSERAGENT}) exten => s,28,Noop(TIMESTAMP=${TIMESTAMP}) exten => s,29,Noop(TXTCIDNAME=${TXTCIDNAME}) exten => s,30,Noop(UNIQUEID=${UNIQUEID}) exten => s,31,Noop(TOUCH_MONITOR=${TOUCH_MONITOR}) exten => s,32,Noop(MACRO_CONTEXT=${MACRO_CONTEXT}) exten => s,33,Noop(MACRO_EXTEN=${MACRO_EXTEN}) exten => s,34,Noop(MACRO_PRIORITY=${MACRO_PRIORITY}) [macro-user-logon] ; check device type exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)})
59

exten => s,2,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1) ; get user's extension exten => s,3,Set(AMPUSER=${ARG1}) exten => s,4,GotoIf($["${AMPUSER}" = ""]?5:9) exten => s,5,BackGround(please-enter-your) exten => s,6,Playback(extension) exten => s,7,Read(AMPUSER,then-press-pound) ; get user's password and authenticate exten => s,8,Wait(1) exten => s,9,Set(AMPUSERPASS=${DB(AMPUSER/${AMPUSER}/password)}) exten => s,10,GotoIf($[${LEN(${AMPUSERPASS})} = 0]?sNOPASSWORD,1) ; do not continue if the user has already logged onto this device exten => s,11,Set(DEVICEUSER=${DB(DEVICE/${CALLERID(number)}/user)}) exten => s,12,GotoIf($["${DEVICEUSER}" = "${AMPUSER}"]?sALREADYLOGGEDON,1) exten => s,13,Authenticate(${AMPUSERPASS}) ; devices can only be mapped to one user - loggoff anyone else who is here exten => s,14,Macro(user-logoff) ; map user to device exten => s,15,Set(AMPUSERDEVICES=${DB(AMPUSER/${AMPUSER}/device)}) exten => s,16,GotoIf($[${LEN(${AMPUSERDEVICES})} = 0]?18) exten => s,17,Set(AMPUSERDEVICES=${AMPUSERDEVICES}&) exten => s,18,Set(AMPUSERDEVICES=${AMPUSERDEVICES}${CALLERID(num ber)}) exten => s,19,Set(DB(AMPUSER/${AMPUSER}/device)=${AMPUSERDEVICES}) ; map device to user exten => s,20,Set(DB(DEVICE/${CALLERID(number)}/user)=${AMPUSER}) ; create symlink from dummy device mailbox to user's mailbox exten => s,21,System(/bin/ln -s /var/spool/asterisk/voicemail/default/${AMPUSER}/ /var/spool/asterisk/voicemail/device/${CALLERID(number)})

60

exten => s-FIXED,1,NoOp(Device is FIXED and cannot be logged into) exten => s-FIXED,2,Playback(ha/phone) exten => s-FIXED,3,SayDigits(${CALLERID(number)}) exten => s-FIXED,4,Playback(is-curntly-unavail) exten => s-FIXED,5,Playback(vm-goodbye) exten => s-FIXED,6,Hangup ;TODO should play msg indicated device cannot be logged into exten => s-ALREADYLOGGEDON,1,NoOp(This device has already been logged into by this user) exten => s-ALREADYLOGGEDON,2,Playback(vm-goodbye) exten => s-ALREADYLOGGEDON,3,Hangup ;TODO should play msg indicated device is already logged into exten => s-NOPASSWORD,1,NoOp(This extension does not exist or no password is set) exten => s-NOPASSWORD,2,Playback(an-error-has-occured) exten => s-NOPASSWORD,3,Playback(vm-goodbye) exten => s-NOPASSWORD,4,Hangup ;TODO should play msg indicated device is already logged into [macro-user-logoff] ; check device type exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)}) exten => s,2,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1) ; remove entry from user's DEVICE key ; delete the symlink to user's voicemail box exten => s,3,System(rm -f /var/spool/asterisk/voicemail/device/${CALLERID(number)}) exten => s,4,Set(DEVAMPUSER=${DB(DEVICE/${CALLERID(number)}/user)}) exten => s,5,Set(AMPUSERDEVICES=${DB(AMPUSER/${DEVAMPUSER}/devic e)}) exten => s,6,DeadAGI(list-itemremove.php,${AMPUSERDEVICES},${CALLERID(number)},AMPUSERD EVICES,&) ; reset user -> device mapping

61

; users can log onto multiple devices, need to just remove device from value exten => s,7,Set(DB(AMPUSER/${DEVAMPUSER}/device)=${AMPUSERDEVICE S}) ; reset device -> user mapping exten => s,8,Set(DB(DEVICE/${CALLERID(number)}/user)=none) exten => s,9,Playback(vm-goodbye) exten => s-FIXED,1,NoOp(Device is FIXED and cannot be logged out of) exten => s-FIXED,2,Playback(an-error-has-occured) exten => s-FIXED,3,Playback(vm-goodbye) exten => s-FIXED,4,Hangup ;TODO should play msg indicated device cannot be logged into [macro-systemrecording] exten => s,1,Goto(${ARG1},1) exten => dorecord,1,Record(/tmp/${CALLERID(number)}ivrrecording:wav) exten => dorecord,n,Wait(1) exten => dorecord,n,Goto(confmenu,1) exten => docheck,1,Playback(/tmp/${CALLERID(number)}ivrrecording) exten => docheck,n,Wait(1) exten => docheck,n,Goto(confmenu,1) exten => confmenu,1,Background(to-listen-to-it&press-1&to-rerecordit&press-star|m||macro-systemrecording) exten => confmenu,n,Read(RECRESULT||1|||4) exten => confmenu,n,GotoIf($["x${RECRESULT}"="x*"]?dorecord,1) exten => confmenu,n,GotoIf($["x${RECRESULT}"="x1"]?docheck,1) exten => confmenu,n,Goto(1) exten => 1,1,Goto(docheck,1) exten => *,1,Goto(dorecord,1) exten => t,1,Playback(goodbye)
62

exten => t,n,Hangup exten => i,1,Playback(pm-invalid-option) exten => i,n,Goto(confmenu,1) exten => h,1,Hangup

; ; ######################################################### ################### ; CallerID Handling ; ######################################################### ################### ;sets the callerid of the device to that of the logged in user [macro-user-callerid] exten => s,1,Noop(user-callerid: ${CALLERID(name)} ${CALLERID(number)}) exten => s,n,GotoIf($["${CHANNEL:0:5}" = "Local"]?report) exten => s,n,GotoIf($["${REALCALLERIDNUM:1:2}" != ""]?start) exten => s,n,Set(REALCALLERIDNUM=${CALLERID(number)}) exten => s,n(start),NoOp(REALCALLERIDNUM is ${REALCALLERIDNUM}) exten => s,n,Set(AMPUSER=${DB(DEVICE/${REALCALLERIDNUM}/user)}) exten => s,n,Set(AMPUSERCIDNAME=${DB(AMPUSER/${AMPUSER}/cidname)} ) exten => s,n,GotoIf($["x${AMPUSERCIDNAME:1:2}" = "x"]?report) exten => s,n,Set(CALLERID(all)=${AMPUSERCIDNAME} <${AMPUSER}>) exten => s,n,Set(REALCALLERIDNUM=${DB(DEVICE/${REALCALLERIDNUM}/ user)}) exten => s,n(report),Noop(TTL: ${TTL} ARG1: ${ARG1}) exten => s,n,GotoIf($[ "${ARG1}" = "SKIPTTL" ]?continue)

63

exten => s,n(report2),Set(_TTL=${IF($["foo${TTL}" = "foo"]?64:$[ ${TTL} 1 ])}) exten => s,n,GotoIf($[ ${TTL} > 0 ]?continue) exten => s,n,Wait(${RINGTIMER}) ; wait for a while, to give it a chance to be picked up by voicemail exten => s,n,Answer() exten => s,n,Wait(2) exten => s,n,Playback(im-sorry&an-error-has-occured&with&callforwarding) exten => s,n,Macro(hangupcall) exten => s,n,Congestion() exten => s,n(continue),NoOp(Using CallerID ${CALLERID(all)}) exten => h,1,Macro(hangupcall) ; overrides callerid out trunks ; arg1 is trunk ; macro-user-callerid should be called _before_ using this macro [macro-outbound-callerid] ; Keep the original CallerID number, for failover to the next trunk. exten => s,1,GotoIf($["${REALCALLERIDNUM:1:2}" != ""]?start) exten => s,n,Set(REALCALLERIDNUM=${CALLERID(number)}) exten => s,n(start),NoOp(REALCALLERIDNUM is ${REALCALLERIDNUM}) ; If this came through a ringgroup or CF, then we want to retain original CID unless ; OUTKEEPCID_${trunknum} is set. ; exten => s,n,GotoIf($["${KEEPCID}" != "TRUE"]?normcid) ;Set to TRUE if coming from ringgroups, CF, etc. exten => s,n,GotoIf($["x${OUTKEEPCID_${ARG1}}" = "xon"]?normcid) exten => s,n,GotoIf($["foo${REALCALLERIDNUM}" = "foo"]?normcid) ;if not set to anything, go through normal processing exten => s,n,Set(USEROUTCID=${REALCALLERIDNUM}) ; We now have to make sure the CID is valid. If we find an AMPUSER with the same CID, we assume it is an internal ; call (would be quite a conincidence if not) and go through the normal processing to get that CID. If a device ; is set for this CID, then it must be internal
64

; exten => s,n,GotoIf($["foo${DB(AMPUSER/${REALCALLERIDNUM}/device)}" = "foo"]?bypass:normcid) exten => s,n(normcid),Set(USEROUTCID=${DB(AMPUSER/${REALCALLERIDN UM}/outboundcid)}) exten => s,n(bypass),Set(EMERGENCYCID=${DB(DEVICE/${REALCALLERIDN UM}/emergency_cid)}) exten => s,n,Set(TRUNKOUTCID=${OUTCID_${ARG1}}) exten => s,n,GotoIf($["${EMERGENCYROUTE:1:2}" = ""]?trunkcid) ; check EMERGENCY ROUTE exten => s,n,GotoIf($["${EMERGENCYCID:1:2}" = ""]?trunkcid) ; empty EMERGENCY CID, so default back to trunk exten => s,n,Set(CALLERID(all)=${EMERGENCYCID}) ; emergency cid for device exten => s,n,Goto(report) exten => s,n(trunkcid),GotoIf($["${TRUNKOUTCID:1:2}" = ""]?usercid) ;check for CID override for trunk (global var) exten => s,n,Set(CALLERID(all)=${TRUNKOUTCID}) exten => s,n(usercid),GotoIf($["${USEROUTCID:1:2}" = ""]?report) ; check CID override for extension exten => s,n,Set(CALLERID(all)=${USEROUTCID}) exten => s,n,GotoIf($["x${CALLERID(name)}"!="xhidden"]?report:hidecid) ; check CID blocking for extension exten => s,n(hidecid),SetCallerPres(prohib_passed_screen) ; Only works with ISDN (T1/E1/BRI) exten => s,n(report),NoOp(CallerID set to ${CALLERID(all)}) ; Privacy Manager Macro makes sure that any calls that don't pass the privacy manager are presented ; with congestion since there have been observed cases of the call continuing if not stopped with a ; congestion, and this provides a slightly more friendly 'sorry' message in case the user is ; legitamately trying to be cooperative. ;
65

; Note: the following options are configurable in privacy.conf: ; ; maxretries = 3 ; default value, number of retries before failing ; minlength = 10 ; default value, number of digits to be accepted as valid CID ; [macro-privacy-mgr] exten => s,1,Set(KEEPCID=${CALLERID(num)}) exten => s,n,GotoIf($["foo${CALLERID(num):0:1}"="foo+"]?CIDTEST2:CIDTEST1) exten => s,n(CIDTEST1),Set(TESTCID=${MATH(1+${CALLERID(num)})}) exten => s,n,Goto(TESTRESULT) exten => s,n(CIDTEST2),Set(TESTCID=${MATH(1+${CALLERID(num):1})}) exten => s,n(TESTRESULT),GotoIf($["foo${TESTCID}"="foo"]?CLEARCID:PRIVM GR) exten => s,n(CLEARCID),Set(CALLERID(num)=) exten => s,n(PRIVMGR),PrivacyManager() exten => s,n,SetCallerPres(allowed_passed_screen); stop gap until app_privacy.c clears unavailble bit exten => s,PRIVMGR+101,Noop(STATUS: ${PRIVACYMGRSTATUS} CID: ${CALLERID(num)} ${CALLERID(name)} CALLPRES: ${CALLLINGPRES}) exten => s,n,Playback(sorry-youre-having-problems) exten => s,n,Playback(goodbye) exten => s,n,Playtones(congestion) exten => s,n,Congestion(5)

; ; ######################################################### ################### ; Inbound Contexts [from] ; ######################################################### ###################

66

[from-sip-external] ;give external sip users congestion and hangup ; Yes. This is _really_ meant to be _. - I know asterisk whinges about it, but ; I do know what I'm doing. This is correct. exten => _.,1,NoOp(Received incoming SIP connection from unknown peer to ${EXTEN}) exten => _.,n,Set(DID=${IF($["${EXTEN:1:2}"=""]?s:${EXTEN})}) exten => _.,n,Goto(s,1) exten => s,1,Ringing exten => s,n,GotoIf($["${ALLOW_SIP_ANON}"="yes"]?fromtrunk,${DID},1) exten => s,n,Set(TIMEOUT(absolute)=15) exten => s,n,Answer exten => s,n,Wait(2) exten => s,n,Playback(ss-noservice) exten => s,n,Playtones(congestion) exten => s,n,Congestion(5) exten => h,1,NoOp(Hangup) exten => i,1,NoOp(Invalid) exten => t,1,NoOp(Timeout) [from-internal] ; applications are now mostly all found in from-internal-additional in _custom.conf include => parkedcalls include => from-internal-custom ;allow phones to dial other extensions include => ext-fax ;allow phones to access generated contexts ; ; MODIFIED (PL) ; ; Currently the include for findmefollow is being auto-generated before ext-local which is the desired behavior. ; However, I haven't been able to do anything that I know of to force this. We need to determine if it should ; be hardcoded into here to make sure it doesn't change with some configuration. For now I will leave it out ; until we can discuss this.
67

; include => from-internal-additional include => ext-local-confirm ; This causes grief with '#' transfers, commenting out for the moment. ; include => bad-number exten => s,1,Macro(hangupcall) exten => h,1,Macro(hangupcall) ;-----------------------------------------------------------------------; [bad-number] ;-----------------------------------------------------------------------; This is where all calls go that don't have any other destination provided ; ;-----------------------------------------------------------------------[bad-number] exten => _X.,1,Wait(1) exten => _X.,n,Playback(silence/1&cannot-complete-as-dialed&checknumber-dial-again,noanswer) exten => _X.,n,Wait(1) exten => _X.,n,Congestion(20) exten => _X.,n,Hangup() exten => _*.,1,Wait(1) exten => _*.,n,Playback(silence/1&feature-not-availline&silence/1&cannot-complete-as-dialed&check-number-dialagain,noanswer) exten => _*.,n,Wait(1) exten => _*.,n,Congestion(20) exten => _*.,n,Hangup() ;-----------------------------------------------------------------------[from-zaptel] exten => _X.,1,Set(DID=${EXTEN}) exten => _X.,n,Goto(s,1) exten => s,1,NoOp(Entering from-zaptel with DID == ${DID}) ; Some trunks _require_ a RINGING be sent before an Answer. exten => s,n,Ringing() ; If ($did == "") { $did = "s"; } exten => s,n,Set(DID=${IF($["${DID}"= ""]?s:${DID})})
68

exten => s,n,NoOp(DID is now ${DID}) exten => s,n,GotoIf($["${CHANNEL:0:3}"="Zap"]?zapok:notzap) exten => s,n(notzap),Goto(from-pstn,${DID},1) ; If there's no ext-did,s,1, that means there's not a no did/no cid route. Hangup. exten => s,n,Macro(hangup) exten => s,n(zapok),NoOp(Is a Zaptel Channel) exten => s,n,Set(CHAN=${CHANNEL:4}) exten => s,n,Set(CHAN=${CUT(CHAN,-,1)}) exten => s,n,Macro(from-zaptel-${CHAN},${DID},1) ; If nothing there, then treat it as a DID exten => s,n,NoOp(Returned from Macro from-zaptel-${CHAN}) exten => s,n,Goto(from-pstn,${DID},1) exten => fax,1,Goto(ext-fax,in_fax,1) ; ; ; ; ########################################## ## Ring Groups with Confirmation macros ## ########################################## Used by followme and ringgroups

;-----------------------------------------------------------------------; [macro-dial-confirm] ;-----------------------------------------------------------------------; This has now been incorporated into dialparties. It still only works with ringall ; and ringall-prim strategies. Have not investigated why it doesn't work with ; hunt and memory hunt. ; ;-----------------------------------------------------------------------[macro-dial-confirm] ; This was written to make it easy to use macro-dial-confirm instead of macro-dial in generated dialplans. ; This takes the same paramaters, with an additional paramater of the ring group Number ; ARG1 is the timeout ; ARG2 is the DIAL_OPTIONS ; ARG3 is a list of xtns to call - 203-222-240-123123123#-211 ; ARG4 is the ring group number

69

; This sets a unique value to indicate that the channel is ringing. This is used for warning slow ; users that the call has already been picked up. ; exten => s,1,Set(DB(RG/${ARG4}/${CHANNEL})=RINGING) ; We need to keep that channel variable, because it'll change when we do this dial, so set it to ; fallthrough to every sibling. ; exten => s,n,Set(__UNIQCHAN=${CHANNEL}) ; The calling ringgroup should have set RingGroupMethod appropriately. We need to set two ; additional parameters: ; ; USE_CONFIRMATION, RINGGROUP_INDEX ; ; Thse are passed to inform dialparties to place external calls through the [grps] context ; exten => s,n,Set(USE_CONFIRMATION=TRUE) exten => s,n,Set(RINGGROUP_INDEX=${ARG4}) exten => s,n,Set(ARG4=) ; otherwise it gets passed to dialparties.agi which processes it (prob bug) exten => s,n,Macro(dial,${ARG1},${ARG2},${ARG3}) ; delete the variable, if we are here, we are done trying to dial and it may have been left around ; exten => s,n,DBDel(RG/${RINGGROUP_INDEX}/${CHANNEL}) exten => s,n,Set(USE_CONFIRMATION=) exten => s,n,Set(RINGGROUP_INDEX=) ;-----------------------------------------------------------------------;-----------------------------------------------------------------------; [macro-auto-confirm] ;------------------------------------------------------------------------

70

; This macro is called from ext-local-confirm to auto-confirm a call so that other extensions ; are aware that the call has been answered. ; ;-----------------------------------------------------------------------[macro-auto-confirm] exten => s,1,Set(__MACRO_RESULT=) exten => s,n,DBDel(${BLKVM_OVERRIDE}) exten => s,n,DBDel(RG/${ARG1}/${UNIQCHAN}) ;-----------------------------------------------------------------------; [macro-auto-blkvm] ;-----------------------------------------------------------------------; This macro is called for any extension dialed form a queue, ringgroup ; or followme, so that the answering extension can clear the voicemail block ; override allow subsequent transfers to properly operate. ; ;-----------------------------------------------------------------------[macro-auto-blkvm] exten => s,1,Set(__MACRO_RESULT=) exten => s,n,DBDel(${BLKVM_OVERRIDE}) ;-----------------------------------------------------------------------; [ext-local-confirm] ;-----------------------------------------------------------------------; If call confirm is being used in a ringgroup, then calls that do not require confirmation are sent ; to this extension instead of straight to the device. ; ; The sole purpose of sending them here is to make sure we run Macro(auto-confirm) if this ; extension answers the line. This takes care of clearing the database key that is used to inform ; other potential late comers that the extension has been answered by someone else. ; ;-----------------------------------------------------------------------[ext-local-confirm]
71

exten => _LC-.,1,Noop(IN ext-local-confirm with - RT: ${RT}, RG_IDX: ${RG_IDX}) exten => _LC-.,n,dial(${DB(DEVICE/${EXTEN:3}/dial)},${RT},M(autoconfirm^${RG_IDX})${DIAL_OPTIONS}) ;-----------------------------------------------------------------------; [macro-confirm] ;-----------------------------------------------------------------------; CONTEXT: macro-confirm ; PURPOSE: added default message if none supplied ; ; Follom-Me and Ringgroups provide an option to supply a message to be ; played as part of the confirmation. These changes have added a default ; message if none is supplied. ; ;-----------------------------------------------------------------------[macro-confirm] exten => s,1,Set(LOOPCOUNT=0) exten => s,n,Noop(CALLCONFIRMCID: ${CALLCONFIRMCID}) ; We set ABORT rather than CONTINUE, as we want the server to forget about this channel ; if it's declined, hung up, or timed out. We don't want it to continue on to the next ; step in the dialplan, which could be anything! exten => s,n,Set(__MACRO_RESULT=ABORT) ; ARG1 is the announcement to play to tell the user that they've got a call they need ; to confirm. Something along the lines of 'You have an incoming call. Press 1 to accept, 9 to reject' exten => s,n,Set(MSG1=${IF($["foo${ARG1}" != "foo"]?${ARG1}:"incoming-call-1-accept-2-decline")}) exten => s,n(start),Read(INPUT|${MSG1}|1||1|5) ; So. We've now read something, or nothing. We should check to make sure that the call hasn't

72

; already been answered by someone else. If it has, send this call to toolate exten => s,n,GotoIf(${DB_EXISTS(RG/${ARG3}/${UNIQCHAN})}?check:toolate) ; We passed that test, so it means the call hasn't been answered. Has this user pushed 1? If so, ; then go to OK. exten => s,n(check),GotoIf($["${INPUT}"="1"]?ok) ; If they've pushed 9, then they definately don't want the call. Just pretend there was no response ; and go to noanswer (or 2 since that will be default for asterisk) exten => s,n,GotoIf($["${INPUT}"="9"]?noanswer) exten => s,n,GotoIf($["${INPUT}"="2"]?noanswer) exten => s,n,GotoIf($["${INPUT}"="3"]?playcid) ; Increment LOOPCOUNT, and check to make sure we haven't played it 5 times by now. We assume that ; the person is able to push '1' in a reasonably short time. exten => s,n,Set(LOOPCOUNT=$[ ${LOOPCOUNT} + 1 ]) exten => s,n,GotoIf($[ ${LOOPCOUNT} < 5 ]?start) ; If we're here, that means we've played it MORE than 5 times. Set __MACRO_RESULT=ABORT, well, just ; coz, and goto fin, which is the last line, meaning it returns to the previous Dial, and pretends as ; if nothing has happened. exten => s,n(noanswer),Set(__MACRO_RESULT=ABORT) exten => s,n,Goto(fin) ; Test play callerid ; exten => s,n(playcid),Noop(Playing CID: ${CALLCONFIRMCID}) exten => s,n,SayDigits(${CALLCONFIRMCID}) exten => s,n,Goto(start) ; If we're here, it's because the call was already accepted by someone else.

73

exten => s,n(toolate),Set(MSG2=${IF($["foo${ARG2}" != "foo"]?${ARG2}:"incoming-call-no-longer-avail")}) exten => s,n,Playback(${MSG2}) exten => s,n,Goto(noanswer) ; If we made it here, it's because the call _WAS_ accepted, AND it's still ringing. We delete the ; database entry (so that the DB_EXISTS line above will trigger a 'toolate' jump), and set the ; MACRO_RESULT variable to NOTHING. This is the magic string that joins both legs of the call together exten => s,n(ok),DBDel(RG/${ARG3}/${UNIQCHAN}) exten => s,n,DBDel(${BLKVM_OVERRIDE}) exten => s,n,Set(__MACRO_RESULT=) ; The end. exten => s,n(fin),NoOp(Finished) exten => h,1,Noop(Hangup Extension in macro-confirm) exten => h,n,Macro(hangupcall) ;-----------------------------------------------------------------------; ######################################################### ################### ; Extension Contexts [ext] ; ######################################################### ################### [ext-fax] exten => s,1,Answer exten => s,2,Goto(in_fax,1) exten => in_fax,1,StopPlayTones exten => in_fax,2,GotoIf($["${FAX_RX}" = "system"]?3:analog_fax,1) exten => in_fax,3,Macro(faxreceive) exten => in_fax,4,Hangup exten => analog_fax,1,GotoIf($["${FAX_RX}" = "disabled"]?4:2) ;if fax is disabled, just hang up exten => analog_fax,2,Set(DIAL=${DB(DEVICE/${FAX_RX}/dial)});
74

exten => analog_fax,3,Dial(${DIAL},20,d) exten => analog_fax,4,Hangup ;exten => out_fax,1,wait(7) exten => out_fax,1,txfax(${TXFAX_NAME}|caller) exten => out_fax,2,Hangup exten => h,1,system(/var/lib/asterisk/bin/fax-process.pl --to ${EMAILADDR} --from ${FAX_RX_FROM} --subject "Fax from ${URIENCODE(${CALLERID(number)})} ${URIENCODE(${CALLERID(name)})}" --attachment fax_${URIENCODE(${CALLERID(number)})}.pdf --type application/pdf --file ${FAXFILE}); exten => h,2,Hangup() ;this is where parked calls go if they time-out. Should probably rering [default] include => ext-local exten => s,1,Playback(vm-goodbye) exten => s,2,Macro(hangupcall)

[incoming] exten => s,1,Echo ;for testing the connection ;exten => s,1,Playback,demo-thanks ;for playing a file

75

2.11 Lampiran Topologi jaringan VOIP server UNILA

76

77

Anda mungkin juga menyukai