Asterisk 1.6.1 di OpenSUSE

From OnnoWiki
Jump to: navigation, search

Referensi:


Overview

In my previous post I promise to share some of my experience in preparing emergency operation center for disaster management. One of the software we implement in this project is Asterisk. I use Asterisk 1.6.1.5 from openSUSE repository. Actually I built a custom 64 bit appliance using KDE 4.3 from factory repositories through SUSE Studio and took Asterisk from openSUSE Build Service repositories. Well It’s about 2 months ago (by the time I write this post), and I hope it still there. If you want it you can download the image from here. I also included DAHDI (Digium Asterisk Hardware Device Interface), but during the implementation I have a problem with Indonesia PSTN telephone signaling so I should download dahdi trunk version from digium subversion server to make the digium card works.

Here are the hardware I use:

  1. 2 HP tower based server with 8 GB memory (it is overkill actually, but the owner insist it) running in high availability. See the pictures here and here.
  2. 10 PSTN lines
  3. 3 Digium TDM 410P cards (with 4 FXO ports per card and hardware echo canceler) per server
  4. several RJ12 coupler
  5. RJ 12 cables
  6. 2 Zed-3 GS8 GSM gateway, each with 2 GSM modules
  7. Several Polycom IP-330 with PoE
  8. Polycom KIRK Wireless Server 600V3
  9. Several Polycom DECT 3040 Wireless Handset

Well, Digium and Polycom price are expensive but the quality of the sound is very good. There are some alternatives for the IP Phone like Grandstream and Aastra that also can be used.

In this project, Asterisk will be use to setup the voip communication between this site in Denpasar/Bali with the headquarter (HQ) in Jakarta as well as with other regional center in Java and Sumatera. Also Asterisk will act as traditional PBX to connect this site to PSTN lines as well as to GSM/CDMA lines. Every conversation through the PABX will be recorded by monitor application in Asterisk.

Before we go any further lets discuss a logical design about our setup. There is one HQ and several remote site including this one in Bali. This site is special because it’s also act as second node beside HQ that can receive and transmit voip traffic to other center. The setup of every site is similar like the diagram below.

IP PBX Setup

All the digium card provide 12 lines of PSTN, in this case we only use 10 lines. We then use RJ 12 coupler so that every line goes to 2 PBX server, PABXSV1 and PABXSV2. The PABXSV2 will become the backup asterisk in case the PABXSV1 is downed. We use vrrpd to control the service so that PABXSV2 can take over all the service from PABXSV1. More on this later.

I use stock asterisk and dahdi from OBS. While the asterisk is ok, dahdi in the OBS is not sufficient for Indonesia telephone lines (at least at the time I made the appliance). The root cause of the problem is that Indonesia PSTN line provided by Telkom is already equipped with the CID (caller identifier) but the service is not open to the end customer until the customer pay the service charge. But actually the CID is there and asterisk knows it but cannot open it. So it can answer the ring but if another call comes, suddenly it confuses how to handle it and hangup the line. Off course we should make a good configuration not just downloading the trunk version.

I should thanks some good people who currently help me maintain the server, I should mentioned here:

  1. Pak Wayan Sudana, Ketua KPLI Bali
  2. Mas Adhi Wus, linuxer dari Denpasar
  3. Mas Yan Arief (dkk), openSUSE user dari Yogyakarta
  4. Jambi ada yang berminat (silakan kontak saya)

In the next post I will explain some configuration that I used, till then keep safe and have a lot of fun.


Step by Step Configuration

In this second part I will explain step-by-step configuration to use our appliance to build an Asterisk PABX server. Without further ado, here is the list:

  1. Install the Digium card on the PCI slot
  2. Install our appliance. You can also use any linux distribution, download asterisk from its website and install it.
  3. There are several softwares I forget when I made the appliance, it is not the mandatory (dependencies) but they are useful when we want to use asterisk optimally. They are: mpg123, sox, libmad, and festival. The easiest way to install it in openSUSE is using zypper. Check it first where they reside in repositories and add the repositories accordingly. mpg123 and sox are in the packman repositoriy, libmad in OBS (please check with webpin) and festival in oss. Then as root run: "zypper install mpg123, sox, libmad, festival".
  4. It is always useful to update your installation to update repository, to make sure that all the security update is up to date.
  5. Download the latest dahdi from trunk and install it. Don’t forget you should connected to internet to run this command as root
svn co http://svn.digium.com/svn/dahdi/linux/trunk dahdi-linux
cd dahdi-linux
make

and follow the instructions on the screen.

If all the installation successful, then you will have :

/etc/dahdi/
/etc/asterisk/
/var/lib/asterisk/
/var/spool/asterisk/
/etc/init.d/dahdi
/etc/init.d/asterisk161
/usr/sbin/asterisk
/usr/sbin/dahdi_genconf (and several dahdi-tools files)

Connect the telephone line(s) to your digium. Make sure that all the telephone lines are functioning before you connect it (please pay your bill if you don’t to that yet, otherwise the announcement in the telephone lines will screw up your asterisk :-)).

As root run “/usr/sbin/dahdi_genconf”. This command will generate the automatic configuration for digium card in file /etc/dahdi/system.conf. In my server it contains:

# Autogenerated by /usr/sbin/dahdi_genconf on Tue Nov 17 18:38:30 2009
# If you edit this file and execute /usr/sbin/dahdi_genconf again,    
# your manual changes will be LOST.                                   
# Dahdi Configuration File                                            
#                                                                     
# This file is parsed by the Dahdi Configurator, dahdi_cfg            
#                                                                     
# Span 1: WCTDM/0 "Wildcard TDM410P Board 1" (MASTER)                 
fxsks=1                                                               
echocanceller=mg2,1                                                   
fxsks=2
echocanceller=mg2,2
fxsks=3
echocanceller=mg2,3
fxsks=4
echocanceller=mg2,4

# Span 2: WCTDM/1 "Wildcard TDM410P Board 2"
fxsks=5
echocanceller=mg2,5
fxsks=6
echocanceller=mg2,6
fxsks=7
echocanceller=mg2,7
fxsks=8
echocanceller=mg2,8

# Span 3: WCTDM/2 "Wildcard TDM410P Board 3"
fxsks=9
echocanceller=mg2,9
fxsks=10
echocanceller=mg2,10
fxsks=11
echocanceller=mg2,11
fxsks=12
echocanceller=mg2,12

# Global data
loadzone        = nl
defaultzone     = nl

Actually default loadzone and defaultzone is “us” but I change it to “nl” which is according to ITU is close to Indonesia signaling system. Please check ITU Operational Bulletin No. 781 – 1.II.2003. At least busy tone, congestion tone, and dial tone are running in the same frequency and cadence. If you want you can also rebuild asterisk so that it already contain the frequency and cadence for your country.

Besides /etc/dahdi/system.conf, dahdi_genconf will also automatically configure the file /etc/asterisk/dahdi-channels.conf. In my installation the content of the file is:

; Autogenerated by /usr/sbin/dahdi_genconf on Tue Nov 17 18:38:30 2009
; If you edit this file and execute /usr/sbin/dahdi_genconf again,    
; your manual changes will be LOST.                                   
; Dahdi Channels Configurations (chan_dahdi.conf)                     
;                                                                     
; This is not intended to be a complete chan_dahdi.conf. Rather, it is intended
; to be #include-d by /etc/chan_dahdi.conf that will include the global settings
;                                                                               

; Span 1: WCTDM/0 "Wildcard TDM410P Board 1" (MASTER)
;;; line="1 WCTDM/0/0"                                
signalling=fxs_ks                                     
callerid=asreceived                                   
group=0                                               
context=from-pstn                                     
channel => 1                                          
callerid=                                             
group=                                                
context=default                                       

;;; line="2 WCTDM/0/1"
signalling=fxs_ks     
callerid=asreceived   
group=0               
context=from-pstn     
channel => 2          
callerid=             
group=                
context=default       

;;; line="3 WCTDM/0/2"
signalling=fxs_ks     
callerid=asreceived   
group=0               
context=from-pstn     
channel => 3          
callerid=             
group=                
context=default        

;;; line="4 WCTDM/0/3"
signalling=fxs_ks     
callerid=asreceived   
group=0               
context=from-pstn     
channel => 4          
callerid=             
group=                
context=default        

; Span 2: WCTDM/1 "Wildcard TDM410P Board 2"
;;; line="5 WCTDM/1/0"                       
signalling=fxs_ks                            
callerid=asreceived                          
group=0                                      
context=from-pstn                            
channel => 5                                 
callerid=                                    
group=                                       
context=default                               

;;; line="6 WCTDM/1/1"
signalling=fxs_ks     
callerid=asreceived   
group=0               
context=from-pstn     
channel => 6          
callerid=             
group=                
context=default        

;;; line="7 WCTDM/1/2"
signalling=fxs_ks     
callerid=asreceived   
group=0               
context=from-pstn     
channel => 7          
callerid=             
group=                
context=default       

;;; line="8 WCTDM/1/3"
signalling=fxs_ks     
callerid=asreceived   
group=0               
context=from-pstn     
channel => 8          
callerid=             
group=                
context=default       

; Span 3: WCTDM/2 "Wildcard TDM410P Board 3"
;;; line="9 WCTDM/2/0"                       
signalling=fxs_ks                            
callerid=asreceived                          
group=0                                      
context=from-pstn                            
channel => 9                                 
callerid=                                    
group=                                       
context=default                              

;;; line="10 WCTDM/2/1"
signalling=fxs_ks
callerid=asreceived
group=0
context=from-pstn
channel => 10
callerid=
group=
context=default 

;;; line="11 WCTDM/2/2"
signalling=fxs_ks
callerid=asreceived
group=0
context=from-pstn
channel => 11
callerid=
group=
context=default

;;; line="12 WCTDM/2/3"
signalling=fxs_ks
callerid=asreceived
group=0
context=from-pstn
channel => 12
callerid=
group=
context=default

The core of the asterisk configuration is dialplan. Dialplan manage how asterisk handle all the incoming and outgoing call. It can consist of 3 lines but also can reach tenth or hundreds lines, depends on how the complexity of our configuration. We can also use macro feature on asterisk. Dialplan is placed on /etc/asterisk/extensions.conf. My extensions.conf manage how the incoming call should be handled, how to make outgoing call to PSTN, GSM line and sip extensions, how to make conference call, how to connect to other asterisk server using IAX2 protocol, use the monitor application to record the conversation and how to make greeting. I will explain our extensions.conf in more detail in the next post together with sip.conf, iax.conf, meetme.conf and voicemail.conf.

Stay tuned and have a lot of fun :-)


Connect to PSTN

To enable asterisk to communicate with PSTN lines we should have either a VOIP-PSTN gateway or FXO card. I will not explain about VOIP-PSTN gateway, there are some service providers out there who provides this service for their customers. In my work I use Digium TDM 410P with 4 FXO port per card. There are some alternatives in the market like Sangoma, Rhino, etc, the important is we should make sure that it works with Asterisk either with dahdi driver or zaptel/zapata driver. Also if possible select the card that already has hardware echo-canceler. Echo is a problem in voip communication, and if you have card with no echo-canceler than your server CPU will busy do the job.

Just remember that Digium cards are no longer use zapata driver, and some changes has been made to the configuration file name and location, /etc/zaptel.conf become /etc/dahdi/system.conf and /etc/asterisk/zapata.conf become /etc/asterisk/chan_dahdi.conf

In the client site you can use any SIP client hardwares or softwares. Ekiga and Emphaty are the good choice for you who prefer GTK libraries and KCall and KPhone are for you who prefer Qt libraries. IP phone hardware now widely available in the market from cheap to high price, you can select any brand as long as it compatibles with Asterisk. In this project I choose Polycom IP-330, I also used Grandstream and Aastra in other implementation. In this implementation the owner also ask me to use Polycom KIRK Wireless Server 600V3 with Polycom DECT Handset 3040.

Now the time for the dialplan, extensions.conf, which is the core of asterisk implementation, as an example let me introduce you with my configuration. It is a good habit to always backup default asterisk configuration, and start the new configuration from the scratch.

My extensions.conf is:

; extensions.conf - the Asterisk dial plan
; Created by M. Edwin Z for xxxxxxxxxxxxxxxx
; medwinz@gmail.com                         
;                                                            
; Static extension configuration file, used by               
; the pbx_config module. This is where you configure all your
; inbound and outbound calls in Asterisk.                     
;                                                             
; This configuration file is reloaded                         
; - With the "dialplan reload" command in the CLI             
; - With the "reload" command (that reloads everything) in the CLI
;                                                                 

[general]
static=yes
writeprotect=yes

[globals]
RINGDELAY => 20
DYNAMIC_FEATURES => automon  

[incoming]
exten => s,1,Answer
exten => s,2,Background(en/greeting-indonesia)
exten => s,3,Hangup()                    

exten => h,1,Hangup()

exten => 9999,1,VoiceMailMain()
exten => asterisk,1,VoicemailMain()

exten => 5000,1,Set(CHANNEL(language)=en) ; conference 1
exten => 5000,2,Meetme(5000)                           
exten => 5000,3,Hangup                                 

exten => 6000,1,Set(CHANNEL(language)=en) ; conference 2
exten => 6000,2,Meetme(6000)                           
exten => 6000,3,Hangup                                 

exten => 7000,1,Set(CHANNEL(language)=en) ; conference 3
exten => 7000,2,Meetme(7000)                           
exten => 7000,3,Hangup                                 

exten => _XXXX,1,Answer
exten => _XXXX,2,Dial(SIP/${EXTEN},${RINGDELAY},t)
exten => _XXXX,3,Voicemail(${EXTEN}@default,u)   
exten => _XXXX,4,Hangup()                        
exten => _XXXX,103,Voicemail(${EXTEN}@default,b) 
exten => _XXXX,104,Hangup

[internal-fxo]
exten => s,1,Answer
exten => s,2,Wait(1)
exten => s,3,Background(en/autoattendant)
exten => s,4,WaitExten(2)               
exten => 5000,1,MeetMe(5000)            
exten => 6000,1,MeetMe(6000)            
exten => 7000,1,MeetMe(7000)            
exten => _XXXX,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m) 
exten => _XXXX,2,Dial(SIP/${EXTEN},${RINGDELAY},t)                                                  
exten => _XXXX,3,Voicemail(su${EXTEN})                                                              
exten => _XXXX,4,Hangup()                                                                           
exten => _XXXX,103,Voicemail(sb${EXTEN})                                                            
exten => _XXXX,104,Hangup()                                                                         

exten => h,1,Hangup()

exten => t,1,Monitor(wav,Call-${CALLERID(num)}-9019-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m) 
exten => t,2,Dial(SIP/9019&SIP/9006&SIP/9007&SIP/9001&SIP/9002&SIP/9015,${RINGDELAY},t)     
exten => t,3,Hangup                                                                         
exten => t,305,Dial(SIP/9001&SIP/9002&SIP/9003&SIP/9004&SIP/9005&SIP/9006&SIP/9007&SIP/9008&SIP/9009&SIP/9010&SIP/9011&SIP/9016&SIP/9017&SIP/9018&SIP/9019)
exten => t,306,Hangup 

include => incoming

[internal-fxs]
include => incoming

[internal-sip]
exten => _1.,1,Dial(IAX2/ygpabxsv:0000@10.1.1.120/${EXTEN:1}@local)
exten => _1.,2,Hangup()                                           

exten => _2.,1,Dial(IAX2/ygpabxsv:0000@10.7.1.120/${EXTEN:1}@local)
exten => _2.,2,Hangup()                                           

;;GSM call to Telkomsel/HALO
exten => _000811.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000811.,2,Dial(SIP/9031/${EXTEN:1})                                                                                     
exten => _000811.,3,Hangup                                                                             

;;GSM call to Telkomsel/Simpati
exten => _000812.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000812.,2,Dial(SIP/9031/${EXTEN:1})                                                          
exten => _000812.,3,Hangup                                                                             

;;GSM call to Telkomsel/Simpati
exten => _000813.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000813.,2,Dial(SIP/9031/${EXTEN:1})                                                          
exten => _000813.,3,Hangup                                                                             

;GSM call to Telkomsel/As
exten => _000852.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000852.,2,Dial(SIP/9031/${EXTEN:1})                                                          
exten => _000852.,3,Hangup                                                                             

;;GSM call to Telkomsel/As
exten => _000853.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000853.,2,Dial(SIP/9031/${EXTEN:1})                                                          
exten => _000853.,3,Hangup                                                                             

;;GSM call to Indosat
exten => _000814.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000814.,2,Dial(SIP/9031/${EXTEN:1})                                                          
exten => _000814.,3,Hangup                                                                             

;;GSM call to Indosat
exten => _000815.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000815.,2,Dial(SIP/9031/${EXTEN:1})                                                          
exten => _000815.,3,Hangup                                                                             

;;GSM call to Indosat
exten => _000816.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000816.,2,Dial(SIP/9031/${EXTEN:1})                                                          
exten => _000816.,3,Hangup                                                                             

;;GSM call to Indosat
exten => _000855.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000855.,2,Dial(SIP/9031/${EXTEN:1})                                                          
exten => _000855.,3,Hangup                                                                             

;;GSM call to Indosat
exten => _000856.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000856.,2,Dial(SIP/9031/${EXTEN:1})                                                          
exten => _000856.,3,Hangup                                                                            
 
;;GSM call to Indosat
exten => _000857.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000857.,2,Dial(SIP/9031/${EXTEN:1})                                                          
exten => _000857.,3,Hangup                                                                             

;;GSM call to Indosat
exten => _000858.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000858.,2,Dial(SIP/9031/${EXTEN:1})                                                          
exten => _000858.,3,Hangup                                                                             

;;GSM call to XL
exten => _000817.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000817.,2,Dial(SIP/9032/${EXTEN:1})                                                          
exten => _000817.,3,Hangup                                                                             

;;GSM call to XL
exten => _000818.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000818.,2,Dial(SIP/9032/${EXTEN:1})                                                          
exten => _000818.,3,Hangup                                                                             

;;GSM call to XL
exten => _000819.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000819.,2,Dial(SIP/9032/${EXTEN:1})                                                          
exten => _000819.,3,Hangup                                                                             

;;GSM call to XL
exten => _000859.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000859.,2,Dial(SIP/9032/${EXTEN:1})                                                          
exten => _000859.,3,Hangup                                                                             

;GSM call to XL
exten => _000878.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000878.,2,Dial(SIP/9032/${EXTEN:1})                                                          
exten => _000878.,3,Hangup                                                                             

;GSM call to 3
exten => _000898.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000898.,2,Dial(SIP/9032/${EXTEN:1})                                                          
exten => _000898.,3,Hangup                                                                             

;GSM call to 3
exten => _000899.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _000899.,2,Dial(SIP/9032/${EXTEN:1})                                                          
exten => _000899.,3,Hangup                                                                             

;;GSM call to Axis
; exten => _000831.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
; exten => _000831.,2,Dial(SIP/9032/${EXTEN:1})                                                          
; exten => _000831.,3,Hangup                                                                             
;;GSM call to Axis
; exten => _000838.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:2}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
;exten => _000838.,2,Dial(SIP/9032/${EXTEN:1})                                                           
;exten => _000838.,3,Hangup                                                                              

include => global
include => incoming

[global]
exten => _0.,1,Monitor(wav,Call-${CALLERID(num)}-${EXTEN:1}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},m)
exten => _0.,2,Dial(DAHDI/g1/${EXTEN:1})                                                          
exten => _0.,3,Hangup                                                                             
exten => _0.,103,Playback(en/tt-allbusy)                                                          
exten => _0.,104,Hangup                                                                           

[recordings]
exten => 500,1,Answer
exten => 500,2,Playback(en/silakanrekamgreeting)
exten => 500,3,Record(en/mymessage:gsm)        
exten => 500,4,Playback(en/pesananda)          
exten => 500,5,Playback(en/mymessage)          
exten => 500,6,Playback(en/tekan1)
exten => 500,7,WaitExten(3)

exten => t,1,Playback(en/maafmohonulangi)
exten => t,2,Goto(500,5)

exten => i,1,Playback(en/pesanandasalah)
exten => i,2,Goto(500,5)

exten => 1,1,System(/bin/mv /var/lib/asterisk/sounds/en/mymessage.gsm  /var/lib/asterisk/sounds/en/autoattendant.gsm)
exten => 1,2,Playback(en/terimakasih)
exten => 1,3,Playback(en/tekan3)

exten => 2,1,Goto(500,1)
exten => 3,1,Goto(500,1)
exten => 4,1,Hangup

include => internal-sip

[local]
;
; Master context for local, toll-free, and iaxtel calls only
;
ignorepat => 9
include => default
include => parkedcalls
include => internal-sip

[default]
include => internal-sip 

I know it seems make pain in your head, so now take a cup of coffee, read the above configuration carefully until it comes up into your dream :-) . I will explain everything in the next post.

Have a lot of fun.


Pranala Menarik