Debian: Asterisk PBX

From ReceptiveIT
Jump to: navigation, search

Overview

Asterisk is an Open Source software based PBX that runs on Linux, BSD and MacOSX. It provides all the features that you would expect from a real hardware phone system, with a flexibility that you probably never thought possible. In short, Asterisk is the holy grail of telephony. Many thanks go out to all developers, and to Digium for making Asterisk a reality.

Installation

The instructions provided here are for Debian GNU/Linux. These instructions might translate to other distributions of Linux.

Install Asterisk

apt-get install asterisk

Was that it? It can't be that easy...

Configuration

For a phone system to be useful, we need to have at least one handset (extension) and one incoming line. This is what is called a 1x1 PBX. In the real world, a 1x1 PBX would be a little overkill, but as an example of how Asterisk works, it is an easily attainable first step.

Configuring your first handset

This example will assume that you have a usable SIP phone to use as a handset for Asterisk. This SIP phone could be a Ethernet based SIP phone, a Ethernet to POTS ATA Device, or a software SIP phone running as an application on a PC. Edit /etc/asterisk/sip.conf and add the following at the bottom of the file

[101]
type=friend
context=default
secret=password
callerid="First Handset" <101>
host=dynamic
disallow=all
allow=g729
allow=gsm
allow=ulaw

Edit /etc/asterisk/extensions.conf and add the folling just after [default]

exten => 101,1,Macro(stdexten,101,SIP/101,80,Ttr)

You should now be able to dial numbers from your SIP phone. You can log into Asterisk from the command line and see events happen in real-time.

asterisk -vvvr

Zaptel Hardware

zaptel.conf - Don't forget that FXO ports are signalled with FXS, and FXS ports are signalled with FXO! The following example sets up a four (4) channel analog FXS card with Australian dial tone.

#
# Zaptel Configuration File
#
loadzone = au
defaultzone=au
fxoks=1-4

Simply setting the country code does not set the correct impedance for the line. By default, the TDM400 hardware sets itself to FCC mode, which is North American lines. If you live in Australia, like me, you will need to edit /etc/modprobe.d/zaptel and add the following line.

options wctdm opermode=AUSTRALIA

Dial Plan

Linksys (Sipura) SPA-3000

Features - 1 x FXO port and 1 x FXS port

This little box has proven to be a good, reliable and cheap way to get a single line into your Asterisk box. While the Digium cards are fantastic, sometimes you just need a single line.

Setting up is quite easy. Log into your SPA-3000 as admin, and in advanced mode.

Regional

Call Progress Tones FXS Port Impedance: 220+820||120nF FXS Port Input Gain: 3 FXS Port Output Gain: -3 Detect ABCD: yes Playback ABCD: yes Caller ID Method: Bellcore(N.Amer,China) FXS Port Power Limit: 3

PSTN Line

Line Enable: yes Proxy and Registration Proxy: {IP address of Asterisk Server} Use Outbound Proxy: yes Outbound Proxy: {IP address of Asterisk Server} Use OB Proxy in Dialog: yes Register: yes Make Call Without Reg: no Register Expires: 3600 Ans Call Without Reg: no Use DNS SRV: no DNS SRV Auto Prefix: no Proxy Fallback Intvl: 3600 Subscriber Information Display Name: {SIP Username} User ID: {SIP Username} Password: {SIP Password} Use Auth ID: no Audio Configuration Preferred Codec: G711u Dial Plans Dial Plan 1: (xx.) Dial Plan 2: (S0<:192.168.198.23>) VoIP-To-PSTN Gateway Setup VoIP-To-PSTN Gateway Enable: yes VoIP Caller Auth Method: none VoIP PIN Max Retry: 3 One Stage Dialing: yes Line 1 VoIP Caller DP: 1 VoIP Caller Default DP: 1 Line 1 Fallback DP: none PSTN-To-VoIP Gateway Setup PSTN-To-VoIP Gateway Enable: yes PSTN CAller Auth Method: none PSTN Ring Thru Line 1: yes PSTN PIN Max Retry: 3 PSTN CID For VoIP CID: no PSTN Caller Default DP: 2 FXO Timer Values (sec PSTN Answer Delay: 0 PSTN Disconnect Detection Detect CPC: yes Detect Polarity Reversal: yes Detect PSTN Long Silence: no Detect VoIP Long Silence: no PSTN Long Silence Duration: 30 VoIP Long Silence Duration: 30 PSTN Silence Threshold: medium Min CPC Duration: 0.2 Detect Disconnect Tone: yes Disconnect Tone: 425@-30,425@-30;1(.375/.375/1+2) International Control FXO Port Impedance: 220+820||120nF Ring Frequency Min: 10 SPA To PSTN Gain: 0 Ring Frequency Max: 100 PSTN To SPA Gain: 0 Ring Validation Time: 256ms Tip/Ring Voltage Adjust: 3.1V Ring Indication Delay: 512ms Operational Loop Current Min: 16mA Ring Timeout: 640ms On-Hook Speed: 26ms (Australia) Ring Threshold: 13.5-16.5 Vrms Current Limiting Enable: no Ringer Impedance: High (Normal) Line-In-Use Voltage: 30

We also have to add an entry into the sip.conf file

[pstn]
type=friend
host=dynamic
secret=password
call-limit=2
disallow=all
allow=ulaw
allow=alaw
allow=g723.1
allow=g729
allow=gsm
context=pstnincoming

[4350]
type=friend
context=sipuser
secret=password
auth=md5
callerid="Cordless" <4350>
host=dynamic
nat=yes
dtmfmode=rfc2833
canreinvite=no
reinvite=no
dtmfmode=info
incominglimit=2
mailbox=4350
disallow=all
allow=g729
allow=gsm
allow=ulaw

Next we need to add the PSTN line to the correct context, and the FXS port to the sip phones context, in the extensions.conf file.

[pstnincoming]
# What incoming calls from the PSTN have access to
exten => s,1,Dial(SIP/4351&SIP/4350|30,tr)
exten => s,2,Voicemail(u4351)

[sipuser]
# What VoIP users have access to
include => voip-phones
include => tollcalls

[voip-phones]
# VoIP Extensions
exten => 4350,1,Macro(stdexten,4350,SIP/4350,80,Ttr)
exten => 4350,2,Voicemail(u4350)

BLF and Line Keys

Linksys Handsets

Linksys SPA942 can now do BLF and speeddials really well

Phone Menu - Line Key Extended Function

Asterisk

Phone Menu - Extended Function

fnc=blf+sd+cp;sub=848@$PROXY;ext=848@$PROXY;vid=1

Asterisk Config

sip.conf

subscribecontext = handsets
notifyringing = yes
notifyhold = yes

Each handsets need a call limit

call-limit=1

Inbound context

[pstn-incoming]
exten => 62160812,1,NoOp(Reception Test)
exten => 62160812,n,Set(TIMEOUT(digit)=2)
exten => 62160812,n,Set(SWITCHMODE=${DB(cvh/nightswitch)})
exten => 62160812,n,GotoIf($["${SWITCHMODE}" = "0"]?normal)
exten => 62160812,n,GotoIf($["${SWITCHMODE}" = "1"]?meeting)
exten => 62160812,n,GotoIf($["${SWITCHMODE}" = "2"]?morning)
exten => 62160812,n,GotoIf($["${SWITCHMODE}" = "3"]?night)
exten => 62160812,n,Goto(hangup)
exten => 62160812,n(meeting),NoOp(Meeting)
exten => 62160812,n,Playback(custom/ceh-meetingmsg)
exten => 62160812,n,Goto(hangup)
exten => 62160812,n(morning),NoOp(Morning)
exten => 62160812,n,Playback(custom/ceh-morningmsg)
exten => 62160812,n,Goto(hangup)
exten => 62160812,n(night),NoOp(Night)
exten => 62160812,n,Playback(custom/ceh-ahmsg)
exten => 62160812,n,Goto(hangup)
exten => 62160812,n(normal),NoOp(Business Hours)
exten => 62160812,n,Macro(directdial,812,1)
exten => 62160812,n,Goto(hangup)
exten => 62160812,n(hangup),NoOp(Hanging up)
exten => 62160812,n,Hangup

BLF Context

[ceh-callroute]
exten => 848,hint,Custom:ceh
exten => 848,1,NoOp(CEH Nightswitch)
exten => 848,n,Set(SWITCHMODE=${DB(ceh/nightswitch)})
exten => 848,n,Background(custom/press&custom/0&custom/2&custom/activate&custom/daymode,m)
exten => 848,n,Background(custom/press&custom/1&custom/2&custom/activate&custom/meetingmode,m)
exten => 848,n,Background(custom/press&custom/2&custom/2&custom/activate&custom/morningmode,m)
exten => 848,n,Background(custom/press&custom/3&custom/2&custom/activate&custom/nightmode,m)

exten => 0,1,NoOp(Set Day Mode)
exten => 0,n,Set(DB(ceh/nightswitch)=0)
exten => 0,n,Set(DEVICE_STATE(Custom:ceh)=NOT_INUSE)
exten => 0,n,Playback(custom/daymode&custom/hasbeenset)
exten => 0,n,Hangup()
exten => 1,1,NoOp(Set Meeting Mode)
exten => 1,n,Set(DB(ceh/nightswitch)=1)
exten => 1,n,Set(DEVICE_STATE(Custom:ceh)=INUSE)
exten => 1,n,Playback(custom/meetingmode&custom/hasbeenset)
exten => 1,n,Hangup()
exten => 2,1,NoOp(Set Morning Mode)
exten => 2,n,Set(DB(ceh/nightswitch)=2)
exten => 2,n,Set(DEVICE_STATE(Custom:ceh)=INUSE)
exten => 2,n,Playback(custom/morningmode&custom/hasbeenset)
exten => 2,n,Hangup()
exten => 3,1,NoOp(Set Night Mode)
exten => 3,n,Set(DB(ceh/nightswitch)=3)
exten => 3,n,Set(DEVICE_STATE(Custom:ceh)=INUSE)
exten => 3,n,Playback(custom/nightmode&custom/hasbeenset)
exten => 3,n,Hangup()

Receiving Faxes

There is a cool little utility called IAXModem which is a software modem that creates analog tones digitally...

IAXModem becomes an IAX client to asterisk. When a call comes in on the fax line, asterisk passes the call to IAXModem, which does the software modem thing, and then communicates to Hylafax over a tty that IAXModem generates.

Asterisk Configuration

Edit iax.conf and add the following

[299]
type=friend
host=dynamic
context=incoming-faxes
jitterbuffer=no
disallow=all
allow=slin
secret=iaxmodem
auth=md5
qualify=yes

IAXModem Configuration

Edit /etc/iaxmodem/iaxmodem-cfg.ttyIAX0 and enter the following

device          /dev/ttyIAX0
owner           uucp:uucp
mode            660
port            4570
refresh         300
server          127.0.0.1
peername        299
secret          iaxmodem
cidname         Business Name
cidnumber       61262001122
codec           slinear

Hylafax Configuration

Adding a Fax Modem

Here is a sample /etc/hylafax/config.ttyIAX0

# $Id: iaxmodem,v 1.1 2006/04/02 23:18:30 darren Exp $

#
# prototype config for the IAXmodem softmodem which uses
# the spandsp soft-DSP library
#

#
CountryCode:            61
AreaCode:               2
FAXNumber:              "62001122"
LongDistancePrefix:     0
InternationalPrefix:    0011
DialStringRules:        etc/dialrules
ServerTracing:          0xFFF
SessionTracing:         0xFFF
RecvFileMode:           0600
LogFileMode:            0600
DeviceMode:             0600
RingsBeforeAnswer:      1
SpeakerVolume:          off
GettyArgs:              "-h %l dx_%s"
LocalIdentifier:        "Business Name"
TagLineFont:            etc/lutRS18.pcf
TagLineFormat:          "From %%l|%c|Page %%P of %%T"
MaxRecvPages:           200
ModemReadyState:        D
#

#
#
# Modem-related stuff: should reflect modem command interface
# and hardware connection/cabling (e.g. flow control).
#
ModemType:              Class1          # use this to supply a hint

#
# The modem is taken off-hook during initialization, and then
# placed back on-hook when done to prevent glare.
#
ModemResetCmds:         "ATH1\nAT+VCID=1"       # enables CallID display
ModemReadyCmds:         ATH0

Class1AdaptRecvCmd:     AT+FAR=1
Class1TMConnectDelay:   400             # counteract quick CONNECT response
Class1RMQueryCmd:       "!24,48,72,96"  # V.17 fast-train recv doesn't work well

CallIDPattern:          "NMBR="
CallIDPattern:          "NAME="
CallIDPattern:          "ANID="
CallIDPattern:          "NDID="
# Uncomment these if you really want them, but you probably don't.
#CallIDPattern:          "DATE="
#CallIDPattern:          "TIME="
Emailing Faxes

You need to add a file called /etc/hylafax/FaxDispatch. Here is a simple example.

FILETYPE=pdf;
SENDTO=FaxMaster;
MIMENCODE=bin/uuencode_it;

Here is a more comprehensive example

##      $Id: FaxDispatch,v 1.2 2003/05/04 23:49:41 darren Exp $
##
## Default FaxDispatch file - routes all inbound faxes to FaxMaster as PDF
##
## Consult the faxrcvd(8C) man page for more information
##

#SENDTO=faxMaster;                               # by default email to FaxMaster
#FILETYPE=pdf;                                   # in PDF format 


##
## This excerpt from the man page gives you an idea of what's possible here
##
## You can route by sender's TSI
#case "$SENDER" in
#       *1*510*526*1212*) SENDTO=sam;;          # Sam's test rig in Berkeley
#       *1*415*390*1212*) SENDTO=raster@asd;;   # 7L Xerox room, used for scanning
#       *5107811212)      SENDTO=peebles@mti;;  # stuff from home
#esac

## and/or by device
#case "$DEVICE" in
#       ttyS1)            SENDTO=john;;         # all faxes received on ttyS1
#       ttyLT0)           SENDTO=mary@home;;    # all faxes received on ttyLT0
#esac

## and/or by device
FOLDER="/var/spool/hylafax/recvq/"
FULLPATH="${FOLDER}${FILENAME}.tif"
case "$DEVICE" in
ttyS14)   mv $FULLPATH /var/spool/hylafax/recvq/dept1/;;    # all faxes received on ttyS14
ttyS15)   mv $FULLPATH /var/spool/hylafax/recvq/dept2/;;    # all faxes received on ttyS15
esac

## and/or by caller id
#case "$CIDNUMBER" in
#       435*)        SENDTO=lee; FILETYPE=pdf;; # all faxes from area code 435
#       5059627777)  SENDTO=amy; FILETYPE=tif;; # Amy wants faxes in TIFF
#esac

Recording Calls

Note: Recording calls may or may not be legal in your area. If you decide to record your calls, make sure you are legally in a position to do so.

The following code, inserted into extensions.conf will start recording a call if the number starts with 8.

;
; Record calls
;
exten => _8.,1,Set(DIREC=/var/spool/asterisk/voicerecord)
exten => _8.,2,Set(CALLFILENAME=${TIMESTAMP}-${CALLERIDNUM}-${EXTEN:1})
exten => _8.,3,MixMonitor(${DIREC}/${CALLFILENAME}.wav|av(0)V(0))
exten => _8.,4,Dial(${TRUNK}/${EXTEN:1}|60,t)
exten => _8.,5,Congestion

It would be a good idea to schedule a cron job to convert the wav files to ogg or mp3 after hours to conserve disk space.

CDR using PostgreSQL

apt-get install postgresql-8.1

edit /etc/asterisk/cdr_pgsql

[global]
hostname=localhost
port=5432
dbname=asterisk
password=password
user=postgres

Switch User to the Postgres user

su postgres

Create the database

createdb asterisk

Create the CDR table

psql asterisk < /usr/share/doc/asterisk-doc/contrib/scripts/postgres_cdr.sql

Create the user

createuser -A -D -P asterisk
Enter password for new user:
Enter it again:
CREATE USER

Log into PostgreSQL

psql asterisk

Grant access to the user

grant INSERT on cdr to asterisk;
grant SELECT on cdr to asterisk;
grant ALL on cdr_acctid_seq to asterisk;

edit /etc/postgresql/8.1/main/pg_hba.conf

local   all         postgres                          ident sameuser

# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD

# "local" is for Unix domain socket connections only
local   all         all                               md5 sameuser
# IPv4 local connections:
host    all         all         127.0.0.1/32          md5
# IPv6 local connections:
host    all         all         ::1/128               md5

Music On Hold

Here is a script to convert mp3 files to wav for non-processor intensive music on hold.

#!/bin/bash
FROMDIR="/root/mp3"
TODIR="/var/lib/asterisk/moh"
for i in $FROMDIR/*.mp3
do
BASEFILE=$(basename $i .mp3)
echo Converting $BASEFILE
mpg123 -s --rate 44100 --mono $FROMDIR/$BASEFILE.mp3 > $TODIR/$BASEFILE.raw
sox -r 44100 -2 -s -c 1 $TODIR/$BASEFILE.raw -r 8000 -c 1 $TODIR/$BASEFILE.wav
#sox $TODIR/$BASEFILE.wav -t gsm -r 8000 -b -c 1 $TODIR/$BASEFILE.gsm
#sox $TODIR/$BASEFILE.wav -t ul -r 8000 -b -c 1 $TODIR/$BASEFILE.pcm
rm -f $TODIR/$BASEFILE.raw
done

/etc/asterisk/musiconhold.conf

[default]
mode=files
directory=/var/lib/asterisk/moh