Download from Wow! eBook
THIRD EDITION Asterisk™: The Definitive Guide Leif Madsen, Jim Van Meggelen, and Russell Bryant Beijing • Cambridge • Farnham • Köln • Sebastopol • Tokyo
Asterisk™: The Definitive Guide, Third Edition by Leif Madsen, Jim Van Meggelen, and Russell Bryant Copyright © 2011 Leif Madsen, Jim Van Meggelen, and Russell Bryant. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://my.safaribooksonline.com).
Table of Contents Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii 1. A Telephony Revolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Resource Modules Addon Modules Test Modules File Structure Configuration Files Modules The Resource Library The Spool Logging The Dialplan Hardware Asterisk Versioning Previous Release Methodologies The New Release Methodology Conclusion 21 23 24 24 24 24 25 25 25 25 26 26 26 27 28 3. Installing Asterisk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
The [files] Section The [compat] Section modules.conf The [modules] Section indications.conf musiconhold.conf Converting Music to a Format That Works Best with Asterisk Conclusion 75 75 75 76 77 79 79 81 5. User Device Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 Telephone Naming Concepts Hardphones, Softphones, and ATAs Configuring Asterisk How Channel Configuration Files Work with the Dialplan sip.conf iax.
7. Outside Connectivity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 The Basics of Trunking Fundamental Dialplan for Outside Connectivity PSTN Circuits Traditional PSTN Trunks Installing PSTN Trunks VoIP PSTN Termination PSTN Origination VoIP to VoIP Configuring VoIP Trunks Emergency Dialing Conclusion 131 132 133 134 136 144 144 145 147 147 154 156 8. Voicemail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Conclusion—Easy Reference Cheat Sheet 194 10. Deeper into the Dialplan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Conclusion 236 12. Internet Call Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 DNS and SIP URIs The SIP URI SRV Records Accepting Calls to Your System Dialing SIP URIs from Asterisk ENUM and E.164 E.164 and the ITU ENUM Asterisk and ENUM ISN, ITAD, and freenum.
Using Local Channels Queue Statistics: The queue_log File Conclusion 293 296 299 14. Device States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16. Relational Database Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A Prompt-Recording Application Speech Recognition and Text-to-Speech Text-to-Speech Speech Recognition Conclusion 394 395 395 396 396 18. External Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Disabling Digium FFA (Should You Want to Test spandsp) Incoming Fax Handling Fax to TIFF Fax to Email Fax Detection Outgoing Fax Handling Transmitting a Fax from Asterisk File Format for Faxing An Experiment in Email to Fax Fax Pass-Through Using Fax Buffers in chan_dahdi.conf Conclusion 446 447 447 447 448 449 450 450 451 454 454 455 20. Asterisk Manager Interface (AMI) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22. Clustering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489 Traditional Call Centers Hybrid Systems Pure Asterisk, Nondistributed Asterisk and Database Integration Single Database Replicated Databases Asterisk and Distributed Device States Distributing Device States over a LAN Distributing Device States over a WAN Multiple Queues, Multiple Sites Conclusion 489 490 492 493 493 495 496 496 497 499 501 23.
Backends Example Channel Events SNMP Installing the SNMP Module for Asterisk Configuring SNMP for Asterisk Using OpenNMS Monitoring Asterisk with OpenNMS Conclusion 540 546 551 551 552 558 559 25. Web Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561 Flash Operator Panel Queue Status and Reporting Queue Status Display Queue Reporting Call Detail Records A2Billing Conclusion 562 562 563 563 563 564 564 26. Security . . . . . . . .
Passionate Community Some Things That Are Now Possible The Future of Asterisk Speech Processing High-Fidelity Voice Video Wireless Unified Messaging Peering Challenges Opportunities 582 582 586 587 588 588 589 590 590 591 594 A. Understanding Telephony . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597 B. Protocols for VoIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 617 C.
Foreword “There’s more than one way to do it.” I’ve been working with Asterisk for nine years, and this motto becomes more true with each release, each added feature, and each clever person who attacks a telecommunications problem with this incredibly flexible toolkit.
to install the package, open up some of the configuration files, and start looking at examples. From the basic beginnings of a PBX that Mark Spencer coded in 1999, the Asterisk project, with the help of thousands of developers, has moved from simply connecting phone calls and has matured into a platform that can handle voice, video, and text across dozens of virtual and physical interface types.
If you’re an experienced Asterisk developer or integrator, I’m sure this book will have a few “Hey, that’s a neat way to do it!” moments for you, which is one of the joys of Asterisk. If this is your first project with Asterisk, I’d like to welcome you to the huge community of users and developers dedicated to making Asterisk better.
Preface This is a book for anyone who uses Asterisk. Asterisk is an open source, converged telephony platform, which is designed primarily to run on Linux. Asterisk combines more than 100 years of telephony knowledge into a robust suite of tightly integrated telecommunications applications. The power of Asterisk lies in its customizable nature, complemented by unmatched standards compliance. No other PBX can be deployed in so many creative ways.
Organization The book is organized into these chapters: Chapter 1, A Telephony Revolution This is where we chop up the kindling and light the fire. Welcome to Asterisk! Chapter 2, Asterisk Architecture Discusses the file structure of an Asterisk system. Chapter 3, Installing Asterisk Covers obtaining, compiling, and installing Asterisk. Chapter 4, Initial Configuration Tasks Describes some initial configuration tasks for your new Asterisk system.
Chapter 14, Device States Introduces the concept of device states and how they can be used as presence indicators. Chapter 15, The Automated Attendant Covers how to build a menuing system using the Asterisk dialplan. Chapter 16, Relational Database Integration Discusses various ways that Asterisk can be integrated with a database. Chapter 17, Interactive Voice Response Goes over how Asterisk can be used to build applications that act on input provided by a caller.
we felt that it might still be useful to some readers, so we’ve left it in the book as an appendix. Appendix B, Protocols for VoIP Delves into all the particularities of Voice over IP. This was also a chapter in old versions of this book. Appendix C, Preparing a System for Asterisk Contains information you should be aware of and take into consideration when planning an Asterisk deployment. Software This book is focused on documenting Asterisk version 1.
Download from Wow! eBook This icon indicates a warning or caution. Using Code Examples This book is here to help you get your job done. In general, you may use the code in this book in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission.
We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at: http://oreilly.com/catalog/9780596517342 To comment or ask technical questions about this book, send email to: bookquestions@oreilly.com For more information about our books, conferences, Resource Centers, and the O’Reilly Network, see our website at: http://www.oreilly.com Find us on Facebook: http://facebook.com/oreilly Follow us on Twitter: http://twitter.
on Asterisk, OpenSER, and OpenSIPS; J. Oquendo, Security Guru; Tzafrir Cohen, font of knowledge about security and lots of other stuff; Jeff Gehlbach, for SNMP; Ovidiu Sas, for your encyclopedic knowlege of SIP; Tomo Takebe, for some SMDI help; Steve Underwood, for help with fax and spandsp; and Richard Genthner and John Covert, for helping with LDAP.
Finally, and most importantly, thanks go to Mark Spencer, the original author of Asterisk and founder of Digium, for Asterisk, for Pidgin (http://www.pidgin.im), and for contributing his creations to the open source community. Asterisk is your legacy! Leif Madsen It sort of amazes me where I started with Asterisk, and where I’ve gone with Asterisk. In 2002, while attending school, a bunch of my friends and myself were experimenting with voice over the Internet using Microsoft’s MSN product.
Project (http://www.asteriskdocs.org), with the goal of writing an Asterisk book for the community. That project became the basis of the first edition of this book, Asterisk: The Future of Telephony.
Asterisk has proven that open source telecom is a lasting idea, and the open source telecom landscape is nowadays complemented by more than just Asterisk. Projects like Freeswitch, sipXecs (from SipFoundry), OpenSER/Kamailio/OpenSIPS, and many, many more (and more to come) help to round out the ecosystem. I want to take this opportunity to thank my very good friend Leif Madsen, who has been with me through all three editions.
To my wife, Julie, I cannot thank you enough for all the love and support you have given me. Thank you for keeping my life balanced and happy. You are the best. I love you! To my parents, thank you for giving me so many great opportunities in my life to explore different things and find what I really enjoy. You taught me to work hard and never give up. To Leif and Jim, thank you for your invitation to contribute to this book.
CHAPTER 1 A Telephony Revolution First they ignore you, then they laugh at you, then they fight you, then you win. —Mahatma Gandhi When we first set out—nearly five years ago—to write a book about Asterisk, we confidently predicted that Asterisk would fundamentally change the telecommunications industry. Today, the revolution we predicted is all but complete.
b) develop the required skills through instruction, practice, and a good book on the subject. Asterisk and VoIP: Bridging the Gap Between Traditional and Network Telephony Voice over IP (VoIP) is often thought of as little more than a method of obtaining free long-distance calling. The real value (and—let’s be honest—challenge as well) of VoIP is that it allows voice to become nothing more than another application in the data network.
but it seemed unlikely that anyone was ever going to. At that point it was clear that if he wanted a revolution, he was going to have to start it himself. And so the Zapata Telephony Project was born: Since this concept was so revolutionary, and was certain to make a lot of waves in the industry, I decided on the Mexican revolutionary motif, and named the technology and organization after the famous Mexican revolutionary Emiliano Zapata.
corporate risk-analysis process. While no one can seriously claim to have a complete picture of what this thing should look like, there is no shortage of opinions and ideas.§ Many people new to Asterisk see it as unfinished. Perhaps these people can be likened to visitors to an art studio, looking to obtain a signed, numbered print. They often leave disappointed, because they discover that Asterisk is the blank canvas, the tubes of paint, the unused brushes waiting.
the hackers will be able to quickly respond to changing trends in security and fine-tune the telephone system in response to both corporate policy and industry best practices. Like other open source systems, Asterisk will be able to evolve into a far more secure platform than any proprietary system, not in spite of its hacker roots, but rather because of them.
Obviously, new users do not fit any particular kind of mold. While some will happily spend hours experimenting and reading various blogs describing the trials and tribulations of others, many people who have become enthusiastic about this technology are completely uninterested in such pursuits.
Asterisk-Users This is where most Asterisk users hang out. This list generates several hundred messages per day and has over ten thousand subscribers. While you can go here for help, you are expected to have done some reading on your own before you post a query. Asterisk Wiki Sites The Asterisk Wiki (which exists in large part due to the tireless efforts of James Thompson—thanks James!) is a source of much enlightenment and confusion.
The Asterisk Documentation Project The Asterisk Documentation Project was started by Leif Madsen and Jared Smith, but several people in the community have contributed. The goal of the documentation project is to provide a structured repository of written work on Asterisk. In contrast with the flexible and ad hoc nature of the Wiki, the Docs project is passionate about building a more focused approach to various Asterisk-related subjects.
CHAPTER 2 Asterisk Architecture First things first, but not necessarily in that order. —Doctor Who Asterisk is very different from other, more traditional PBXs, in that the dialplan in Asterisk treats all incoming channels in essentially the same manner. In a traditional PBX, there is a logical difference between stations (telephone sets) and trunks (resources that connect to the outside world).
Figure 2-1. Asterisk vs. PBX architecture Modules Asterisk is built on modules. A module is a loadable component that provides a specific functionality, such as a channel driver (for example, chan_sip.so), or a resource that allows connection to an external technology (such as func_odbc.so). Asterisk modules are loaded based on the /etc/asterisk/modules.conf file. We will discuss the use of many modules in this book.
• • • • • • • • Channel drivers Codec translators Format interpreters Dialplan functions PBX modules Resource modules Addons modules Test modules In the following sections we will list each module available within these categories, briefly identify its purpose, and give our opinion on its relative popularity and/or importance (while some modules are proven and deservedly popular, others are quite old, are barely ever used anymore, and are only maintained for the purpose of backwardcompatibility).
And now, without further ado, let’s take a look at the modules, grouped by module type. Applications Dialplan applications are used in extensions.conf to define the various actions that can be applied to a call. The Dial() application, for example, is responsible for making outgoing connections to external resources and is arguably the most important dialplan application. The available applications are listed in Table 2-1. Table 2-1.
Name Purpose Popularity/Status app_echo Loops received audio back to source channel Useful app_exec Contains Exec(), TryExec(), and ExecIf(); executes a dialplan application based on conditions Useful app_externalivr Controls Asterisk as with an AGI, only asynchronously Useful app_fax Provides SendFax() and ReceiveFax() Usefulb app_festival Enables basic text to speech using Festival TTS engine Usable app_flash Performs a hook-switch flash on channels (primarily analog) Useful app_follo
Name Purpose Popularity/Status app_read Requests input of digits from callers and assigns input to a variable Useful app_readexten Requests input of digits from callers and passes call to a designated extension and context Usable app_readfile Loads contents of a text file into a channel variable Deprecated—see the FILE() function in func_env app_record Records received audio to a file Useful app_rpt Provides a method to interface with an audio board for the app_rpt project Limited app_sayu
a b c d Name Purpose Popularity/Status app_while Includes While(), EndWhile(), ExitWhile(), and ContinueWhile(); provides while-loop functionality in the dialplan Useful app_zapateller Generates SIT tone to discourage telemarketers Usable The use of (DISA) is considered to be a security risk. Requires a suitable DSP engine to handle encoding/decoding of fax signaling (see Chapter 19). If you are a developer. Requires an external speech recognition application.
Table 2-3.
Channel Drivers Without channel drivers, Asterisk would have no way to make calls. Each channel driver is specific to the protocol or channel type it supports (SIP, ISDN, etc.). The channel module acts as a gateway to the Asterisk core. Asterisk’s channel drivers are listed in Table 2-5. Table 2-5.
Codec Translators The codec translators (Table 2-6) allow Asterisk to convert audio stream formats between calls. So if a call comes in on a PRI circuit (using G.711) and needs to be passed out a compressed SIP channel (e.g., using G.729, one of many codecs that SIP can handle), the relevant codec translator would perform the conversion.† If a codec (such as G.729) uses a complex encoding algorithm, heavy use of transcoding can place a massive burden on the CPU.
If you store a recording in several formats (such as WAV, GSM, etc.), Asterisk will determine the least costly format§ to use when a channel requires that recording. Table 2-7. Format interpreters Name Plays files stored in Popularity/Status format_g723 G.723 .g723 Insignificant format_g726 G.726 .g726 Insignificant format_g729 G.729 .g729 Useful format_gsm RPE-LTP (original GSM codec) .gsm Usable format_h263 H.263—video .h263 Usable format_h264 H.264—video .
Name Purpose Popularity/Status func_callcompletion Gets/sets call completion configuration parameters for the channel New func_callerid Gets/sets CallerID Useful func_cdr Gets/sets CDR variable Useful func_channel Gets/sets channel information Useful func_config Includes AST_CONFIG(); reads variables from config file Usable func_connectedline Changes connected line information on supported handsets New func_curl Uses cURL to obtain data from a URI Useful func_cut Slices and dices st
Download from Wow! eBook Name Purpose Popularity/Status func_sprintf Performs string format functions similar to C function of same name Useful func_srv Perform SRV lookups in the dialplan Useful func_strings Includes over a dozen string manipulation functions Useful func_sysinfo Gets system information such as RAM, swap, load average, etc.
Table 2-10.
a b Name Purpose Popularity/Status res_security_log Enables security logging New res_smdi Provides voicemail notification using the SMDI protocol Limited res_snmp Provides system status information to an SNMP-managed network Usable res_speech Generic speech recognition API Limitedb res_timing_dahdi Provides timing using the DAHDI kernel interface Useful res_timing_kqueue Provides timing using a kernel feature in some BSDs, including Mac OS X New res_timing_pthread Provides timing usin
Test Modules Test modules are used by the Asterisk development team to validate new code. They are constantly changing and being added to, and are not useful unless you are developing Asterisk software. If you are an Asterisk developer, however, the Asterisk Test Suite may be of interest to you as you can build automated tests for Asterisk and submit those back to the project, which runs on several different operating systems and types of machines.
The Resource Library There are several resources that require external data sources. For example, music on hold (MOH) can’t happen unless you have some music to play. System prompts also need to be stored somewhere on the hard drive. The /var/lib/asterisk folder is where system prompts, AGI scripts, music on hold, and other resource files are stored. The Spool The spool is where Linux stores files that are going to change frequently, or will be processed by other processes at a later time.
Download from Wow! eBook Hardware Asterisk is capable of communicating with a vast number of different technologies. In general, these connections are made across a network connection; however, connections to more traditional telecom technologies, such as the PSTN, require specific hardware.
number increasing by one each time a new feature release was created. The goal was to provide new feature releases every 3–4 months (which would be branched from trunk), providing a shorter and clearer upgrade path for administrators. If you needed a new feature, you’d only have to wait a few months and could then upgrade to the next branch. Tags from these branches look like this: • 1.6.0.1 -- 1.6.0.2 -- 1.6.0.3 -- 1.6.0.4 -- etc. • 1.6.1.1 -- 1.6.1.2 -- 1.6.1.3 -- 1.6.1.4 -- etc. • 1.6.2.1 -- 1.6.2.
While the development team still wants to provide access to new features and core changes on a more regular basis (every 12 months being the goal), there is recognition that it is also good to provide long-term support to a stable, popular version of Asterisk. You can think of the Asterisk 1.4 branch as being a long-term support (LTS) version. The 1.6.0, 1.6.1, and 1.6.
CHAPTER 3 Installing Asterisk I long to accomplish great and noble tasks, but it is my chief duty to accomplish humble tasks as though they were great and noble. The world is moved along, not only by the mighty shoves of its heroes, but also by the aggregate of the tiny pushes of each honest worker. —Helen Keller In this chapter we’re going to walk through the installation of Asterisk from the source code. Many people shy away from this method, claiming that it is too difficult and timeconsuming.
We have chosen to install on CentOS and Ubuntu because they are the most popular options, but Asterisk is generally distribution-agnostic. Asterisk will even install on Solaris, BSD, or OS X† if you like. We won’t be covering them in this book, though, as Asterisk is most heavily developed on the Linux platform. Asterisk Packages There are also packages that exist for Asterisk that can be installed using popular package-management programs such as yum or apt-get. You are welcome to experiment with them.
Some of the most popular Asterisk-based projects include: AsteriskNOW http://www.asterisk.org/asterisknow Trixbox http://www.trixbox.org Elastix http://www.elastix.org PBX in a Flash http://www.pbxinaflash.net We recommend that you check them out.‡ Installation Cheat Sheet If you just want the nitty-gritty on how to get Asterisk up and running quickly, perform the following at the shell prompt.
Some additional configuration of text files is required on Ubuntu. See “Enable NTP for accurate system time” on page 43. 3. On CentOS, add a new system user: CentOS (32 and 64 bit) adduser asteriskpbx && passwd asteriskpbx && yum install \ sudo && visudo See “Adding a system user” on page 39 for specific information. For an Ubuntu install, we are assuming that the user created during the installation process is asteriskpbx. 4.
$ make $ sudo make install $ sudo make config 8. Install additional sound prompts from menuselect: $ cd ~/src/asterisk-complete/asterisk/1.8/ $ make menuselect $ sudo make install 9.
; PBX modules currently not needed noload => pbx_ael.so noload => pbx_dundi.so ; Channel noload => noload => noload => noload => noload => noload => noload => modules currently not needed chan_oss.so chan_mgcp.so chan_skinny.so chan_phone.so chan_agent.so chan_unistim.so chan_alsa.so ; Application modules currently not needed noload => app_nbscat.so noload => app_amd.so noload => app_minivm.so noload => app_zapateller.so noload => app_ices.so noload => app_sendtext.so noload => app_speech_utils.
15. Save your changes and your module configuration is done. Your system is ready to configure your dialplan and channels. Distribution Installation Because Asterisk relies so heavily on having priority access to the CPU, it is essential that you install Asterisk onto a server without any graphical interface, such as the X Windowing system (Gnome, KDE, etc.). Both CentOS and Ubuntu ship a GUI-free distribution designed for server usage. We will cover instructions for both distributions.
Choose your language and make a keyboard selection.* If you’re in North America, you will probably just select the defaults. If you’ve previously formatted your hard drive, you will be asked to initialize the drive, which will erase all data. Select Yes . The installer will ask if you want to remove the existing partitioning scheme and create a new one. Select Remove all partitions on selected drives and create default layout. If a more appropriate option exists, select that instead.
At the Review and modify the partitioning layout screen, you can create a separate volume for /var. Selecting Yes will bring up the Partitioning tool. To partition the drive accurately, you need to know what the hard drive size is; this may not jibe with what is stamped on the outside of the drive because you have to tell the tool how to chop up the drive.
Base system update Once you’ve rebooted your system, you need to run the yum update command to make sure you have the latest base packages. To do this, log in using the username root and the password you created during installation. Once logged in, run the following: # yum update Is this ok [y/N]: y When prompted to install the latest packages, press y and wait for the packages to update. If you’re asked to accept a GPG key, press y .
Adding a system user The Ubuntu server install process asks you to add a system user other than root, but CentOS does not. In order to be consistent in the book and to be more secure, we’re going to add another system user and provide it sudo access.§ To add the new user, execute the adduser command: # adduser asteriskpbx # passwd asteriskpbx Changing password for user asteriskpbx. New UNIX password: Retype new UNIX password: Now we need to provide the asteriskpbx user sudo access.
Start by opening the hidden file .bash_profile located within the asteriskpbx home directory with an editor. We’re then going to append :/usr/sbin:/sbin to the end of the line starting with PATH: $ vim ~/.bash_profile PATH=$PATH:$HOME/bin:/usr/sbin:/sbin As previously, save the file by pressing Esc and then typing :wq and pressing Enter . With the operating system installed, you’re ready to install the dependencies required for Asterisk.
You will be presented with a list of countries. Once you’ve found your country and highlighted it, press Enter . You will then be asked if you would like to use the keyboard layout detector. If you know which keyboard type you have, you can select No and then pick it from a list of formats. If you are utilizing the keyboard layout detector, you will be prompted to press a series of keys.
After entering your username, you’ll be asked to supply a password, and then asked to confirm the password you’ve entered. Ubuntu does a good job of providing a secure system by not providing direct access to root, but rather using the sudo application, which allows you to run commands as root without being the root user. Enter a username,# such as asteriskpbx, and a secure password to continue. You’ll use these to log into the system once the installer ends.
failed to detect that has information loaded into the MBR, it’s nice to be able to skip modifying it. If this is the only operating system installed on your server, select Yes . When the system has finished the install, you’ll be asked to remove any media in the drives and to reboot the system by selecting Continue, at which point the installation will be complete and the system will reboot.
The default on Ubuntu is to run a time sync server without ever changing the time on your own machine. This won’t work for our needs, so we’ll need to change the configuration file slightly. Because of this, we need to guide you through using a command line editor. The nano editor is already installed on your Ubuntu machine and is remarkably easy to use†: $ sudo nano /etc/ntp.conf Your terminal will switch to full-screen output.
dependencies; only the most commonly used modules will be built. If additional dependencies are required for other modules used later in the book, instructions will be provided as necessary. Please be aware that the dependency information on CentOS 64-bit does not take into account that 32-bit libraries should not be installed.
Third-Party Repositories For certain software dependencies, a third-party repository may be necessary. This appears to be most often the case when using CentOS. A couple of repositories that seem to be able to provide all the extra dependencies required are RPMforge (http://dag .wieers.com/rpm/) and EPEL (Extra Packages for Enterprise Linux, http://fedoraproject .org/wiki/EPEL).
Getting the Latest Version Asterisk is a constantly evolving project, and there are many different versions of the software that you can implement. In Chapter 2, we talked about Asterisk versioning. The concept of how Asterisk is versioned is important to understand because the versioning system for Asterisk has undergone a few changes of methodology over the years. So, if you’re not up to speed on Asterisk versioning, we strongly recommend that you go back and read “Asterisk Versioning” on page 26.
How to Install It With the source files downloaded you can compile the software and install it. The order for installing is: 1. LibPRI‡ 2. DAHDI§ 3. Asterisk‖ Installing in this order ensures that any dependencies for DAHDI and Asterisk are installed prior to running the configuration scripts, which will subsequently ensure that any modules dependent on LibPRI or DAHDI will be built. So, let’s get started. LibPRI LibPRI is a library that adds support for ISDN (PRI and BRI).
DAHDI The Digium Asterisk Hardware Device Interface, or DAHDI (formerly known as Zaptel), is the software Asterisk uses to interface with telephony hardware. We recommend that you install it even if you have no hardware installed, because DAHDI is a dependency required for building the timing module res_timing_dahdi and is used for Asterisk dialplan applications such as MeetMe().
You will need to have Internet access when running the make all command, as it will attempt to download the latest hardware firmware from the Digium servers. After installing DAHDI, we can move on to installing Asterisk. You can also download the source via wget from http://downloads.aster isk.org/pub/telephony/dahdi-linux-complete/. Asterisk With both DAHDI and LibPRI installed, we can now install Asterisk: $ $ $ $ $ cd ~/src/asterisk-complete/asterisk/1.8 .
Change the last line of the dahdi.rules file to the following: SUBSYSTEM=="dahdi", OWNER="asteriskpbx", GROUP="asteriskpbx", MODE="0660" With that out of the way, we can move on to performing the base configuration that should be done after all installations. Base Configuration Now that we’ve got Asterisk installed, we can get our system up and running. The purpose here is to get Asterisk loaded up and ready to go, as it isn’t doing anything useful yet.
To disable SELinux permanently, modify the /etc/selinux/config file: $ cd /etc/selinux/ $ sudo vim config Change the SELINUX option from enforcing to disabled. Alternatively, you can change the value of enforcing to permissive, which simply logs the errors instead of enforcing the policy. When you’re done modifying the configuration file, you’ll have the following: # This file controls the state of SELinux on the system.
Download from Wow! eBook Running make samples on a system that already has configuration files will overwrite the existing files. Using make samples to Create Sample Configuration Files for Future Reference Even though we are not going to use the sample configuration files that come with Asterisk, the fact is that they are an excellent reference.
Open the asterisk.conf file with an editor such as nano or vim: Uncomment the run user and rungroup lines, and modify them so that they each contain asteriskpbx as the assigned value. Open the /etc/asterisk/asterisk.conf file with vim: $ vim /etc/asterisk/asterisk.conf Then modify the file by uncommenting the two lines starting with runuser and run group and modifying the value to asteriskpbx.
The Asterisk Shell Command Asterisk can be run either as a daemon or as an application. In general, you will want to run it as an application when you are building, testing, and troubleshooting, and as a daemon when you put it into production. The command to start Asterisk is the same regardless of whether you’re running it as a daemon or an application: asterisk However, without any arguments, this command will assume certain defaults and start Asterisk as a background application.
-T This option will add a timestamp to CLI output. -x This command allows you to pass a string to Asterisk that will be executed as if it had been typed at the CLI. As an example, to get a quick listing of all the channels in use without having to start the Asterisk console, simply type asterisk -rx 'core show channels' from the shell, and you’ll get the output you are looking for. -g This option instructs Asterisk to dump a core file if it crashes.
Using cat to Quickly Create Files and Add Content to Them There are many cases in a Linux system where it is necessary to create a file, and then add some content to it. This is commonly done by using the touch command to create the file, and then opening it with an editor to add the content. However, there is a lessknown way of doing this that lets you create the file and add the content all at once: • Use the cat program to redirect output to the file you want (use >> to append, or > to overwrite).
; Channel noload => noload => noload => noload => noload => noload => noload => modules chan_oss.so chan_mgcp.so chan_skinny.so chan_phone.so chan_agent.so chan_unistim.so chan_alsa.so ; Application modules noload => app_nbscat.so noload => app_amd.so noload => app_minivm.so noload => app_zapateller.so noload => app_ices.so noload => app_sendtext.so noload => app_speech_utils.so noload => app_mp3.so noload => app_flash.so noload => app_getcpeid.so noload => app_setcallerid.so noload => app_adsiprog.
we’ll just create a default music on hold class so that we have at a minimum some hold music when placing callers on hold: $ cd /etc/asterisk/ $ cat >> musiconhold.conf ; musiconhold.conf [default] mode=files directory=moh Ctrl + D We’ve created a musiconhold.conf file and defined our [default] hold music class.
We’re going to want extra sound prompts installed instead of just the default core sound prompts, and in a better-sounding format than GSM. We can do this with the menuselect system by running make menuselect in the Asterisk source directory. Before exploring that, though, let’s talk about the different menuselect interfaces. menuselect interfaces There are two interfaces available for menuselect: curses and newt.
Figure 3-2. menuselect using the curses interface Installing Dependencies for newt-Based menuselect To get the newt-based menuselect working, you need to have the libnewt development libraries installed: • CentOS: sudo yum install libnewt-devel • Ubuntu: sudo apt-get install libnewt-dev If you’ve previously used menuselect with the curses interface, you need to rebuild. You can do this with the following commands: $ $ $ $ $ $ cd ~/src/asterisk-complete/asterisk/1.8.
You will be presented with a screen such as that in Figure 3-1 or Figure 3-2. You can use the arrow keys on your keyboard to move up and down. The right arrow key will take you into a submenu, and the left arrow key will take you back. You can use the space bar or Enter key to select and deselect modules. Pressing the q key will quit without saving, while the x key will save your selections and then quit.
Once you’ve completed selecting the sound files, press the x key to save and exit menuselect. You then need to install your new prompts by downloading them from the Asterisk downloads site. This is done simply by running make install again: $ sudo make install $ sudo chown -R asteriskpbx:asteriskpbx /var/lib/asterisk/sounds/ The files will be downloaded, extracted, and installed into the appropriate location (/var/lib/asterisk/sounds// by default).
done with the following command, but before doing that look at the current menuselect.makeopts (after disabling all the modules) and locate app_dial in the MENUSE LECT_APPS category and chan_sip in the MENUSELECT_CHANNELS category. After executing the following command, look at the menuselect.makeopts file again, and you will see that those modules are no longer listed: $ menuselect/menuselect --disable-all --enable chan_sip \ --enable app_dial menuselect.makeopts The modules listed in the menuselect.
Download from Wow! eBook The basic steps are: $ $ $ $ cd ~/src/asterisk-complete/asterisk/1.8./ ./configure make make install You don’t need to run sudo make install because we’ve already set the directory ownership to the asteriskpbx user. You should be able to install new files directly into the appropriate directories.
$ cd ~/src/asterisk-complete/ $ mkdir thirdparty/ $ mkdir thirdparty/1.8/ Downloading third-party modules into this directory allows you to easily reinstall those modules when you upgrade. Just follow the installation instructions for your module, many of which will be as simple as rerunning make install from the modules source directory or copying the precompiled binary to the /usr/lib/asterisk/modules/ directory.
make: gcc: command not found This means that the Asterisk configure script is unable to find your C compiler, which typically means you have not yet installed one. Be sure to install the gcc package for your system. Ubuntu CentOS $ sudo apt-get install gcc $ sudo yum install gcc configure: error: C++ preprocessor “/lib/cpp” fails sanity check This error is presented by the Asterisk configure script when you have not installed the GCC C++ preprocessor.
You do not appear to have the sources for the 2.6.18-164.6.1.el5 kernel installed. You will get this error when attempting to build DAHDI without having installed the Linux headers, which are required for building Linux drivers.
Another thing to consider when performing an upgrade is whether you really need to perform the upgrade in the first place. If you’re using a long-term support (LTS)# version of Asterisk and that version is happily working along for you, perhaps there is no reason to upgrade your existing production system. An alternative to upgrading the entire system is simply to add functionality to your system by running two versions simultaneously on separate systems.
how to connect devices to our Asterisk system in order to start placing calls internally and how to connect Asterisk to outside services in order to place phone calls to endpoints connected to the PSTN and accept calls from those endpoints.
CHAPTER 4 Initial Configuration Tasks Careful. We don’t want to learn from this. —Calvin & Hobbes In the last chapter, we covered how to install Asterisk. But where should you get started with configuration? That is the question this chapter answers. There are a few common configuration files that are relevant regardless of what you are using Asterisk to accomplish. In some cases they may not require any modification, but you need to be aware of them. asterisk.conf The asterisk.
The default directory locations and the options you can use to modify them are listed in Table 4-1. For additional information about the usage of these directories, see the File Structure section of Chapter 2. Table 4-1. asterisk.conf [directories] section Option Value/Example Notes astetcdir /etc/asterisk The location where the Asterisk configuration files are stored. astmoddir /usr/lib/asterisk/ modules The location where loadable modules are stored.
Option Value/Example Notes quiet yes Quiet mode reduces the amount of output seen at the console when Asterisk is run in the foreground. This option is set to no by default. timestamp yes Adds timestamps to all output except output from a CLI command. This option is set to no by default. execincludes yes Enables the use of #exec in Asterisk configuration files. This option is set to no by default. console yes Runs Asterisk in console mode.
a b c Option Value/Example Notes minmemfree 1 Sets the minimum number of megabytes of free memory required for Asterisk to continue accepting calls. If Asterisk detects that there is less free memory available than this threshold, new calls will not be accepted. This option is not set by default. cache_record_files yes When doing recording, stores the file in the record_cache_dir until recording is complete. Once complete, it will be moved into the originally specified destination.
The [files] Section This section of asterisk.conf includes options related to the Asterisk control socket. It is primarily used by remote consoles (asterisk -r). The available options are listed in Table 4-3. Table 4-3. asterisk.conf [files] section Option Value/Example Notes astctlpermissions 0660 Sets the permissions for the Asterisk control socket. astctlowner root Sets the owner for the Asterisk control socket. astctlgroup apache Sets the group for the Asterisk control socket.
Although most modules do not use much in the way of resources, and they all load very quickly, it just seems cleaner to our minds to load only those modules that you are planning on using in your system. Additionally, there are security benefits to not loading modules that accept connections over a network. In the past we felt that explicitly loading each desired module was the best way to handle this, but we have since found that this practice creates extra work.
Table 4-5. modules.conf [modules] section Option Value/Example Notes autoload yes Instead of explicitly listing which modules to load, you can use this directive to tell Asterisk to load all modules that it finds in the modules directory, with the exception of modules listed as not to be loaded using the noload directive. The default, and our recommendation, is to set this option to yes. preload res_odbc.so Indicates that a module should be loaded at the beginning of the module load order.
Hacking indications.conf for Fun and Profit If you have too much time on your hands, you can do all sorts of pointless but entertaining things with your indications. For example, fans of Star Wars can make the following change to the end of their indications.
For more information about using Asterisk in different countries, see Chapter 9. musiconhold.conf If you plan on selling Asterisk-based telephone systems and you do not change the default music on hold that ships with Asterisk, you are sending the message, loud and clear, that you don’t really know what you are doing.
CentOS Prerequisite Since CentOS does not have MP3 capability installed with sox, you will have to install mpg123 before you can convert MP3 files for use with Asterisk. First you will need to install the rpmforge repository. To find out which version you need, open your web browser and go to http://dag.wieers.com/rpm/FAQ.php#B. Select the text for the version/architecture you want to install and paste it into your shell: $ rpm -Uhv http://apt.sw.be/redhat ...
In newer versions of sox (e.g., version 14.3.0, which shipped with Ubuntu 10.10), the -w option has changed to -2. Completing file conversion The resulting file will exist in the /tmp folder (or wherever you uploaded to) and needs to be copied to the /var/lib/asterisk/moh folder: $ cp *.sln /var/lib/asterisk/moh You now need to reload musiconhold in Asterisk in order to have it recognize your new files: $ asterisk -rx "module unload res_musiconhold.so" $ asterisk -rx "module load res_musiconhold.
CHAPTER 5 User Device Configuration I don’t always know what I’m talking about, but I know I’m right. —Muhammad Ali In this chapter we’ll delve into the user devices that you might want to connect to Asterisk, typically VoIP telephones of some sort. Configuring a channel in Asterisk for the device to connect through is relatively straightforward, but you also need to configure the device itself so it knows where to send its calls.
While most devices will have a web-based interface for defining parameters, if you’re putting more than one or two phones into production we recommend using a serverbased configuration process, wherein the set is only told the location of a file server. The set will identify itself and download customized files that define the required parameters for that telephone. As an example, these could be XML files on an FTP server.
on any number of variables that are programmed into the system. This is especially relevant in the context of features such as hot-desking. Hot-desking is a feature that allows someone to log into a device and receive his calls at that device. Let’s say we have three sales agents who typically work outside of the office, but spend a couple of days each month in the office to do paperwork.
Download from Wow! eBook Hardphones, Softphones, and ATAs There are three types of endpoints you would typically provide your users with that could serve as a telephone set. They are popularly referred to as hardphones, softphones, and Analog Terminal Adaptors (ATAs). A hardphone is a physical device. It looks just like an office telephone: it has a handset, numbered buttons, etc.
a webcam for video calling, or perhaps an ability to load files from your desktop for faxing. Some of the disadvantages of softphones are the not-always-on nature of the devices, the necessity to put on a headset each time you take a call, and the fact that many PCs will at random times during the day choose to do something other than what the user wants them to do, which might cause the softphone to stop working while some background task hogs the CPU.
Asterisk allows devices using many different protocols to speak to it (and therefore to each other). However, the SIP and IAX2 protocols are the most popular and mature VoIP modules, so we will focus our attention on them. For your first Asterisk build, you might be best off not bothering with the other protocols (such as Skinny/SCCP, Unistim, H.323, and MGCP), and getting comfortable working with SIP and IAX2 first.
the relevant channel configuration file and the extensions.conf file play a role in most calls routed through the system. Figure 5-1 provides a graphical representation of the relationship between the sip.conf and extensions.conf files. When a call comes into Asterisk, the identity of the incoming call is matched in the channel configuration file for the protocol in use (e.g., sip.conf). The channel configuration file also handles authentication and defines where that channel will enter the dialplan.
has taken over the VoIP/telecom industry and been implemented in thousands of devices and PBXs. If you look through the sip.conf.sample file in the ./configs subdirectory of your Asterisk source you will notice a wealth of options available. Fortunately, the default options are normally all you need, and therefore you can create a very simple configuration file that will allow most standard SIP telephones to connect with Asterisk.
wanted, and also that there needs to be an identically named context in extensions.conf to define the call flow for unauthenticated calls. The next option is allowguest, which we’ve disabled as we don’t want to accept any unauthenticated calls at this time. Keep in mind that for some channels you may actually want to accept unauthenticated calls. A common use for allowing unauthenticated calls is for companies that allow dialing by uniform resource identifiers (URIs), like email addresses.
IPv6 in sip.conf As of version 1.8, Asterisk supports IPv6 for both SIP and RTP traffic. All of the configuration options in /etc/asterisk/sip.conf related to IP addresses can accept either an IPv4 or an IPv6 address. As an example, consider the different values for the udpbin daddr option: udpbindaddr value Description 192.168.100.50 Bind to a specific IPv4 address. 2001:db8::1 Bind to a specific IPv6 address 0.0.0.0 Bind to all IPv4 addresses on the system. :: Bind to all IPv4 and IPv6 addresses.
In the [office-phone] template we’ve defined several options required for authentication and control of calls to and from devices that use that template. The first option we’ve configured is the type, which we’ve set to friend. This tells the channel driver to attempt to match on name first, and then IP address. SIP Configuration Matching and the type Option In the example we have provided, the configuration for SIP phones is set with type=friend.
Name Purpose Popularity/Status func_sprintf Performs string format functions similar to C function of same name Useful func_srv Perform SRV lookups in the dialplan Useful func_strings Includes over a dozen string manipulation functions Useful func_sysinfo Gets system information such as RAM, swap, load average, etc.
Hardphones, Softphones, and ATAs There are three types of endpoints you would typically provide your users with that could serve as a telephone set. They are popularly referred to as hardphones, softphones, and Analog Terminal Adaptors (ATAs). A hardphone is a physical device. It looks just like an office telephone: it has a handset, numbered buttons, etc. It connects directly to the network, and it’s what people are referring to when they talk about a VoIP telephone (or a SIP telephone).
Running make samples on a system that already has configuration files will overwrite the existing files. Using make samples to Create Sample Configuration Files for Future Reference Even though we are not going to use the sample configuration files that come with Asterisk, the fact is that they are an excellent reference.
This icon indicates a warning or caution. Using Code Examples This book is here to help you get your job done. In general, you may use the code in this book in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing a CD-ROM of examples from O’Reilly books does require permission.
Asterisk™: The Definitive Guide
Download from Wow! eBook The Asterisk CLI The best way to see what is happening with your Asterisk system is through the Asterisk CLI. This interface provides various levels of output to let you know what is happening on your system, and offers a wealth of useful utilities to allow you to affect your running system. Begin by calling up the Asterisk CLI and reloading the configuration files for your channel modules: $ sudo asterisk -r *CLI> module reload chan_sip.
Typing the following command returns a listing of all the peers that Asterisk knows about (regardless of their state): *CLI> sip show peers Name/username 0000FFFF0001/0000FFFF0001 0000FFFF0002/0000FFFF0002 Host Dyn Nat ACL Port 192.168.1.100 D N 5060 192.168.1.101 D N 5060 Status Unmonitored Unmonitored You may notice that the Name/username field does not always show the full name of the device. This is because this field is limited to 25 characters.
The init script uses the /etc/dahdi/modules file to determine which modules should be loaded to support the hardware in the system. The installation of the init script attempts to automatically set up this file for you, but you should check it to make sure it is correct: # Autogenerated by tools/xpp/dahdi_genconf (Dahdi::Config::Gen::Modules) on # Tue Jul 27 10:31:46 2010 # If you edit this file and execute tools/xpp/dahdi_genconf again, # your manual changes will be LOST.
modules/. If it is there, edit /etc/asterisk/modules.conf to load chan_dahdi.so. If the module is not present on disk, DAHDI was not installed before installing Asterisk; go back and install it now (see “DAHDI” on page 49 for details). You can verify its presence using the following command: *CLI> module show like chan_dahdi.so Module Description chan_dahdi.so DAHDI Telephony Driver 1 modules loaded Use Count 0 Next, you must configure /etc/asterisk/chan_dahdi.conf.
You can verify that Asterisk has loaded your configuration by running the dahdi show channels CLI command: *CLI> dahdi show channels Chan Extension Context pseudo default 1 LocalSets 2 LocalSets 3 LocalSets 4 LocalSets Language MOH Interpret default default default default default Blocked State In Service In Service In Service In Service In Service For detailed information on a specific channel, you can run dahdi show channel 1.
or from the Asterisk CLI: *CLI> dialplan reload You should now be able to dial between your two new extensions. Open up the CLI in order to see the call progression.
Figure 5-2. SIP dialogs Conclusion In this chapter we learned best practices for device naming by abstracting the concepts of users, extension numbers, and devices, and how to define the device configuration and authentication parameters in the channel configuration files. Next, we’ll delve into the magic of Asterisk that is the dialplan, and see how simple things can create great results.
CHAPTER 6 Dialplan Basics Everything should be made as simple as possible, but not simpler. —Albert Einstein The dialplan is the heart of your Asterisk system. It defines how calls flow into and out of the system. A form of scripting language, the dialplan contains instructions that Asterisk follows in response to external triggers. In contrast to traditional phone systems, Asterisk’s dialplan is fully customizable. This chapter introduces the essential concepts of the dialplan.
Sample Configuration Files If you installed the sample configuration files when you installed Asterisk, you will most likely have an existing extensions.conf file. Instead of starting with the sample file, we suggest that you build your extensions.conf file from scratch. Starting with the sample file is not the best or easiest way to learn how to build dialplans. That being said, the sample extensions.
Context names have a maximum length of 79 characters (80 characters – 1 terminating null). All of the instructions placed after a context definition are part of that context, until the next context is defined. At the beginning of the dialplan, there are two special contexts named [general] and [globals].
The Asterisk wiki at https://wiki.asterisk.org/wiki/display/AST/Impor tant+Security+Considerations outlines several steps you should take to keep your Asterisk system secure. (Chapter 26 in this book also deals with security.) It is vitally important that you read and understand this page.
Each step in an extension is composed of three components: • The name (or number) of the extension • The priority (each extension can include multiple steps; the step number is called the “priority”) • The application (or command) that will take place at that step These three components are separated by commas, like this: exten => name,priority,application() Here’s a simple example of what a real extension might look like: exten => 123,1,Answer() In this example, the extension name is 123, the priority is
changes to your dialplan, as you don’t have to keep renumbering all your steps. For example, your dialplan might look something like this: exten exten exten exten exten => => => => => 123,1,Answer() 123,n,do something 123,n,do something else 123,n,do one last thing 123,n,Hangup() Internally, Asterisk will calculate the next priority number every time it encounters an n.‡ Bear in mind that you must always specify priority number 1.
A very common mistake when writing labels is to insert a comma between the n and the (, like this: exten => 123,n,(label),application() ;<-- THIS IS NOT GOING TO WORK This mistake will break that part of your dialplan, and you will get an error stating that the application cannot be found. Applications Applications are the workhorses of the dialplan.
The Playback() application is used for playing a previously recorded sound file over a channel. Input from the user is ignored, which means that you would not use Play back() in an auto attendant, for example, unless you did not want to accept input at that point.‖ Asterisk comes with many professionally recorded sound files, which should be found in the default sounds directory (usually /var/lib/asterisk/sounds/).
As we work through the book, we will be introducing you to many more Asterisk applications. A Simple Dialplan OK, enough theory. Open up the file /etc/asterisk/extensions.conf, and let’s take a look at your first dialplan (which was created in Chapter 5). We’re going to add to that. Hello World As is typical in many technology books (especially computer programming books), our first example is called “Hello World!” In the first priority of our extension, we answer the call.
or from the shell with: $ sudo /usr/sbin/asterisk -rx "dialplan reload" Calling extension 200 from either of your configured phones should reward you with the voice of Allison Smith saying “Hello World.” If it doesn’t work, check the Asterisk console for error messages, and make sure your channels are assigned to the LocalSets context. We do not recommend that you move forward in this book until you have verified the following: 1. Calls between extension 100 and 101 are working 2.
We used the extension start in this example, but we could have used anything we wanted as an extension name, either numeric or alpha. We prefer to use alpha characters for extensions that are not directly dialable, as this makes the dialplan easier to read. Point being, we could have used 123 or xyz123, or 99luftballons, or whatever we wanted instead of start. The word “start” doesn’t actually mean anything to the dialplan; it’s just another extension.
Both Background() and WaitExten() allow the caller to enter DTMF digits. Asterisk then attempts to find an extension in the current context that matches the digits that the caller entered. If Asterisk finds a match, it will send the call to that extension.
Handling Invalid Entries and Timeouts Now that our first voice menu is starting to come together, let’s add some additional special extensions. First, we need an extension for invalid entries. In Asterisk, when a context receives a request for an extension that is not valid within that context (e.g., pressing 9 in the preceding example), the call is sent to the i extension. We also need an extension to handle situations when the caller doesn’t give input in time (the default timeout is 10 seconds).
Argument 1: Destination The first argument is the destination you’re attempting to call, which (in its simplest form) is made up of a technology (or transport) across which to make the call, a forward slash, and the address of the remote endpoint or resource. Common technology types include DAHDI (for analog and T1/E1/J1 channels), SIP, and IAX2. For example, let’s assume that we want to call a DAHDI endpoint identified by DAHDI/ 1, which is an FXS channel with an analog phone plugged into it.
Argument 2: Timeout The second argument to the Dial() application is a timeout, specified in seconds. If a timeout is given, Dial() will attempt to call the specified destination(s) for that number of seconds before giving up and moving on to the next priority in the extension. If no timeout is specified, Dial() will continue to dial the called channel(s) until someone answers or the caller hangs up.
Updating the dialplan Let’s modify extensions 1 and 2 in our menu to use the Dial() application: [TestMenu] exten => start,1,Answer() same => n,Background(main-menu) same => n,WaitExten(5) exten => 1,1,Dial(SIP/0000FFFF0001,10) ; Replace 0000FFFF0001 with your device name same => n,Playback(vm-nobodyavail) same => n,Hangup() exten => 2,1,Dial(SIP/0000FFFF0002,10) ; Replace 0000FFFF0002 with your device name same => n,Playback(vm-nobodyavail) same => n,Hangup() exten => i,1,Playback(pbx-invalid) same => n,Go
of the variable, and a closing curly brace (in the case of LEIF, we would reference the value of the variable with ${LEIF}). Here’s how we might use a variable inside the Dial() application: exten => 301,1,Set(LEIF=SIP/0000FFFF0001) same => n,Dial(${LEIF}) In our dialplan, whenever we refer to ${LEIF}, Asterisk will automatically replace it with whatever value has been assigned to the variable named LEIF. Note that variable names are case-sensitive.
There are many predefined channel variables available for use within the dialplan, which are explained in the Asterisk wiki at https://wiki.asterisk.org/wiki/display/AST/ Channel+Variables. Channel variables are set via the Set() application: exten => 202,1,Set(MagicNumber=42) same => n,SayNumber(${MagicNumber}) You’re going to be seeing a lot more channel variables. Read on. Environment variables Environment variables are a way of accessing Unix environment variables from within Asterisk.
exten => i,1,Playback(pbx-invalid) same => n,Goto(incoming,123,1) exten => t,1,Playback(vm-goodbye) same => n,Hangup() You’ll notice we’ve added pseudonym extension names for our extension numbers. In “Extensions” on page 110, we explained that Asterisk does not care which naming scheme you use to identify an extension.
N Matches any single digit from 2 to 9. [15-7] Matches a single character from the range of digits specified. In this case, the pattern matches a single 1, as well as any number in the range 5, 6, 7. . (period) Wildcard match; matches one or more characters, no matter what they are. If you’re not careful, wildcard matches can make your dialplans do things you’re not expecting (like matching built-in extensions such as i or h).
Pattern-matching examples This pattern matches any seven-digit number, as long as the first digit is 2 or higher: _NXXXXXX The preceding pattern would be compatible with any North American Numbering Plan local seven-digit number. In areas with 10-digit dialing, that pattern would look like this: _NXXNXXXXXX Note that neither of these two patterns would handle long-distance calls. We’ll cover those shortly.
And finally this one: _011. Note the period on the end. This pattern matches any number that starts with 011 and has at least one more digit. In the NANP, this indicates an international phone number. (We’ll be using these patterns in the next section to add outbound dialing capabilities to our dialplan.) Pattern Matches in Other Countries The examples in this section were NANPA-centric, but the basic logic applies in any country.
More Advanced Digit Manipulation The ${EXTEN} variable properly has the syntax ${EXTEN:x:y}, where x is the starting position and y is the number of digits to return.
Conclusion And there you have it—a basic but functional dialplan. There is still much we have not covered, but you’ve got all of the fundamentals. In the following chapters, we’ll continue to build on this foundation. Download from Wow! eBook If parts of this dialplan don’t make sense, you may want to go back and reread a section or two before continuing on to the next chapter.
CHAPTER 7 Outside Connectivity You cannot always control what goes on outside. But you can always control what goes on inside. —Wayne Dyer In the previous chapters, we have covered a lot of important information that is essential to a working Asterisk system. However, we have yet to accomplish the one thing that is vital to any useful PBX: namely, connecting it to the outside world. In this chapter we will rectify that situation.
perspective, the definition of a trunk is not as clear as it used to be (PBX trunks used totally different technology from station circuits), but as a concept, trunks are still very important.
The [globals] section contains two variables, named LOCAL and TOLL.‡ The purpose of these variables is to simplify management of your dialplan should you ever need to change carriers. They allow you to make one change to the dialplan that will affect all places where the specified channel is referred to: [globals] LOCAL=DAHDI/G0 ; assuming you have a PSTN card in your system TOLL=SIP/YourVoipCarrier ; as defined in sip.
Traditional PSTN Trunks There are two types of fundamental technology that phone carriers use to deliver telephone circuits: analog and digital. Analog telephony The first telephone networks were all analog. The audio signal that you generated with your voice was used to generate an electrical signal that was carried to the other end. The electrical signal had the same characteristics as the sound being produced.
The station is responsible for: • Providing a ringer (or at least being able to handle ringing voltage in some manner) • Providing a dialpad (or some way of sending DTMF) • Providing a hook switch to indicate the status of the line A Foreign eXchange (FX) port is named by what it connects to, not by what it does. So, for example, a Foreign eXchange Office (FXO) port is actually a station: it connects to the central office.
• Richer signaling information (especially if using ISDN) • Lower cost for carriers • Lower cost for customers (at higher densities) In an Asterisk system (or any PBX, for that matter), there are several types of digital circuits you might want to connect: T1 (24 channels) Used in Canada and the United States (mostly for ISDN-PRI) E1 (32 channels) Used in the rest of the world (ISDN-PRI or MFC/R2) BRI (2 channels) Used for ISDN-BRI circuits (Euro-ISDN) Note that the physical circuit can be further defined b
As of DAHDI 2.3.0, the requirement to load dahdi_dummy for a timing interface no longer exists. The same functionality has now been integrated into the main dahdi kernel module. The configuration file defining which modules DAHDI will load is in /etc/dahdi/modules. To disable loading of extra modules, all we need to do is edit the modules file and comment out all the modules by placing a hash (#) at the start of each line.
You can then restart your DAHDI process to unload any existing drivers that were loaded, and load just the dahdi_dummy module with the init script: $ sudo /etc/init.d/dahdi restart Unloading DAHDI hardware modules: done Loading DAHDI hardware modules: No hardware timing source found in /proc/dahdi, loading dahdi_dummy Running dahdi_cfg: [ OK ] Before you can start using your hardware, though, you’ll need to configure the /etc/ dahdi/system.
When installing telephony hardware, be sure you update the /etc/dahdi/ modules file to enable the appropriate modules for your hardware and then reload DAHDI with the init script (/etc/init.d/dahdi). You can use the dahdi_genconf modules command to generate the modules file for your system as well.
signalling = pri_cpe channel => 1-23 Some carriers will use Nortel’s DMS switch, which commonly uses the DMS100 protocol instead of National ISDN 2. In this case you would set the switchtype to DMS100: switchtype = dms100 Outside of Canada and the US, PRI circuits will be carried on an E1 circuit. In Europe, an E1 circuit used for PRI will normally have the following characteristics: • Line code: CCS • Framing: HDB3 (high-density bipolar) The /etc/dahdi/system.
America (we don’t recommend using it for any reason), but in some countries in Europe it is widely used and has almost completely replaced analog. BRI support under Asterisk will be different depending on the BRI card you are installing. The manufacturer of your BRI card will provide specific installation instructions for its hardware.
Additionally, OpenR2 contains some sample configuration files for connecting Asterisk to networks in various countries. To read information about some of the country variants, search the /doc/asterisk folder and refer to the documents inside the appropriate subdirectory: $ ls doc/asterisk/ ar br ec mx ve As an example, OpenR2 provides a sample configuration for connecting to Telmex or Axtel in Mexico. We’ll step you through this to give you an idea of the process.
When installing telephony hardware, be sure you update the /etc/dahdi/ modules file to enable the appropriate modules for your hardware and then reload DAHDI with the init script (/etc/init.d/dahdi). You can use the dahdi_genconf modules command to generate the modules file for your system as well. In order to configure an FXO card to work with Asterisk, two files are required. The first is not an Asterisk configuration file, and is thus located in the /etc/dahdi folder on your system.‡ This file, system.
[incoming], because we have decided that all incoming calls should start in this context§: [incoming] exten => s,1,Answer() same => n,Playback(tt-weasels) same => n,Hangup() Obviously, you would not normally want to answer a call and then hang up. Typically, an incoming call will either be answered by an automated attendant, or ring directly to a phone (or group of phones). VoIP In the world of telecom, VoIP is still a relatively new concept.
Calls from the VoIP network will arrive in the dialplan in whatever context you assigned to the incoming SIP channels, and the dialplan will relay the calls out through the PSTN interface. At its very simplest, a portion of a dialplan that supports termination could look like this: [from-voip-network] exten => _X.
such as a PRI circuit, you will normally be able to order DID numbers to be delivered with that circuit. In order to accept a call from a circuit you are using for origination, you will normally need to handle the passing of the phone number that was called. This is because PSTN trunks can typically handle more than one phone number, and thus the carrier needs to identify which number was called so that your Asterisk system will know how to route the call.
VoIP to VoIP Eventually, the need for the PSTN will likely vanish, and most voice communications will take place over network connections. The original thinking behind the SIP protocol was that it was to be a peer-to-peer protocol. Technically, this is still the case. What has happened, however, is that things have gotten a bit more complicated.
over SIP. In our example, we will creatively refer to the two servers as serverA and serverB. The first file that must be modified is /etc/asterisk/sip.conf. This is the main configuration file for setting up SIP accounts. First, this entry must be added to sip.conf on serverA. It defines a SIP peer for the other server: [serverB] ; ; Specify the SIP account type as 'peer'. This means that incoming ; calls will be matched on IP address and port number. So, when Asterisk ; receives a call from 192.168.1.
Now put the following entry in /etc/asterisk/sip.conf on serverB. It is nearly identical to the contents of the entry we put on serverA, but the name of the peer and the IP address were changed: [serverA] type = peer host = 192.168.1.101 username = serverB secret = apples context = incoming disallow = all allow = ulaw At this point you should be able to verify that the configuration has been successfully loaded into Asterisk using some CLI commands. The first command to try is sip show peers.
Next, you will need to create a peer entry in sip.conf for your service provider. Here is a sample peer entry: [myprovider] type = peer host = your.provider.tld username = username secret = password ; Most providers won't authenticate when they send calls to you, ; so you need this line to just accept their calls.
certificates. The first invocation of ast_tls_cert will generate the CA cert and the server cert for serverA. The second invocation of ast_tls_cert will generate the server cert for serverB: $ cd contrib/scripts $ mkdir certs $ ./ast_tls_cert -d certs -C serverA -o serverA $ ./ast_tls_cert -d certs -C serverB -o serverB -c certs/ca.crt -k certs/ca.key $ ls certs ca.cfg ca.crt ca.key serverA.crt serverA.csr serverA.key serverA.pem serverB.crt serverB.csr serverB.key serverB.pem tmp.
to modify that configuration so that Asterisk knows that the calls between the two servers should be encrypted. The only change required is to add the transport = tls option to the peer entry for the other server. On serverA: [serverB] type = peer host = 192.168.1.102 username = serverA secret = apples context = incoming disallow = all allow = ulaw transport = tls On serverB: [serverA] type = peer host = 192.168.1.
-- Executing [1234@incoming:1] Answer("SIP/serverA-00000000", "") in new stack -- Executing [1234@incoming:2] GotoIf("SIP/serverA-00000000", "1?secure:insecure") in new stack -- Goto (incoming,1234,3) -- Executing [1234@incoming:3] NoOp("SIP/serverA-00000000", "Signaling is encrypted.
IAX trunking. One of the more unique features of the IAX protocol is IAX trunking. Trunking an IAX connection could be useful on any network link that will often be carrying multiple simultaneous VoIP calls between two systems. By encapsulating multiple audio streams in one packet, IAX trunking cuts down on the overhead on the data connection, which can save bandwidth on a heavily used network link. IAX encryption.
place for playing around.
Conclusion Eventually, we believe that the PSTN will disappear entirely. Before that happens, however, a distributed mechanism that is widely used and trusted will be needed to allow organizations and individuals to publish addressing information so that they can be found. We’ll explore some of the ways this is already possible in Chapter 12.
CHAPTER 8 Voicemail Just leave a message, maybe I’ll call. —Joe Walsh Before email and instant messaging became ubiquitous, voicemail was a popular method of electronic messaging. Even though most people prefer text-based messaging systems, voicemail remains an essential component of any PBX. Comedian Mail One of the most popular (or, arguably, unpopular) features of any modern telephone system is voicemail. Asterisk has a reasonably flexible voicemail system named Comedian Mail.
And that’s just the tip of the iceberg! The default version of the /etc/asterisk/voicemail.conf file requires a few tweaks in order to provide a configuration that will be suitable to most situations. We’ll begin by going through the various options you can define in voicemail.conf, and then we’ll provide a sample configuration file with the settings we recommend for most deployments. The voicemail.conf file contains several sections where parameters can be defined.
Download from Wow! eBook Option Value/Example Notes won’t appreciate it if you cut her off after three minutes. A setting somewhere between 600 seconds (10 minutes) and 3600 seconds (1 hour) will probably be about right. minsecs 4 Many folks will hang up instead of leaving a message when they call somebody and get voicemail. Sometimes this hangup happens after recording has started, so the mailbox owner gets an annoying twosecond message of somebody hanging up.
Option Value/Example Notes userscontext default If you use the users.conf file (we don’t), you can define here the context where entries are registered. externnotify /path/to/script If you wish to run an external app whenever a message is left, you can define it here. smdienable no If you are using Asterisk as a voicemail server on a PBX that supports SMDI, you can enable it here.
Option Value/Example Notes emailsubject [PBX]: New message $ {VM_MSGNUM} in mailbox $ {VM_MAILBOX} When Asterisk sends an email, you can use this setting to define what the Subject: line of the email will look like. See the voicemail.conf.sample file for more details. emailbody Dear $ {VM_NAME}:\n\n \tjust wanted to let you know you were just left a ${VM_DUR} long message (number ${VM_MSGNUM}) \nin mailbox $ {VM_MAILBOX u might\nwant to check it when you get a chance.
a b c d Option Value/Example Notes the mailboxes for changes, which will trigger proper message waiting indication (MWI) updates. pollfreq 30 Used in concert with pollmailboxes, this option specifies the number of seconds to wait between mailbox polls. imapgreetings no, yes This enables/disables remote storage of greetings in the IMAP folder. For more details, see Chapter 18.
Asterisk comes with a simple script that will greatly improve the security of your voicemail system. It is located in the source code under the folder: /contrib/scripts/voicemailpwcheck.py. We strongly recommend that you copy it to your /usr/local/bin folder (or wherever you prefer to put such things), and then uncomment the externpasscheck= option in your voicemail.conf file. Your voicemail system will then enforce the password security rules you have established.
Option Value/Example Notes a second level of password in the dialplan where another password is specified. Even so, this is not a safe practice. sendvoicemail yes, no This allows users to compose messages to other users from within their mailboxes. searchcontexts yes, no This allows voicemail applications in the dialplan to not have to specify the voicemail context, since all contexts will be searched. This is not recommended.
Option Value/Example Notes forcegreetings yes, no As above, but for greetings. hidefromdir no, yes If you wish, you can hide specific mailboxes from the Directory() application using this setting. tempgreetwarn yes, no Setting this to yes will warn the mailbox owner that she has a temporary greeting set. This can be a useful reminder when people return from trips or vacations. passwordlocation spooldir If you want, you can have mailbox passwords stored in the spool folder for each mailbox.
a b Option Value/Example Notes listen-control-stopkey 13456789 You can use this setting to customize the interrupt playback key. backupdeleted 0 This setting will allow you to specify how many deleted messages are automatically stored by the system. This is similar to a recycle bin. Setting this to 0 disables this feature. Up to 9999 messages can be stored, after which the oldest message will be erased each time another message is deleted. Yes, we found this a bit confusing too.
The Contexts Section All the remaining sections in the voicemail.conf file will be the voicemail contexts, which allow you to segregate groups of mailboxes. In many cases, you will only need one voicemail context, commonly named [default]. This is worth noting, as it will make things simpler in the dialplan: all the voicemail-related applications assume the context default if no context is specified.
serveremail, tz, saycid, review, operator, callback, dialout, and exitcontext. These options should be in option = value pairs, separated by the pipe character (|). The tz option sets the user’s time zone to a time zone previously defined in the [zonemessages] section of voicemail.conf, and the other eight options override the global voicemail settings with the same names. The mailboxes you define in your voicemail.
[zonemessages] eastern=America/New_York|'vm-received' Q 'digits/at' IMp central=America/Chicago|'vm-received' Q 'digits/at' IMp central24=America/Chicago|'vm-received' q 'digits/at' H N 'hours' military=Zulu|'vm-received' q 'digits/at' H N 'hours' 'phonetic/z_p' european=Europe/Copenhagen|'vm-received' a d b 'digits/at' HM [shifteight.org] 100 => 1234,Leif Madsen,leif@shifteight.org 101 => 1234,Jim Van Meggelen,jim@shifteight.org 102 => 1234,Russell Bryant,russell@shifteight.
Table 8-4. VoiceMail() optional arguments Argument Purpose b Instructs Asterisk to play the busy greeting for the mailbox (if no busy greeting is found, the unavailable greeting will be played). d([c]) Accepts digits to be processed by context c. If the context is not specified, it will default to the current context. g(#) Applies the specified amount of gain (in decibels) to the recording. Only works on DAHDI channels.
The VoiceMailMain() Dialplan Application Users can retrieve their voicemail messages, change their voicemail options, and record their voicemail greetings using the VoiceMailMain() application. VoiceMailMain() accepts two arguments: the mailbox number (and optionally the context) to be accessed, and some options. Both arguments are optional.
If callers press 8, they’ll get a directory by first name. If they dial 9, they’ll get the directory by last name. Using a Jitterbuffer When using Asterisk as a voicemail server,§ you may want to add a jitterbuffer in between voicemail and the caller. The purpose of a jitterbuffer is to help deal with the fact that when a call traverses an IP network, the traffic may not arrive with perfect timing and in perfect order.
as WAV and GSM), depending on what you specified as the format in the [general] section of your voicemail.conf file. Your greetings will also be stored in this folder. Asterisk will not create a folder for any mailboxes that do not have any recordings yet (as would be the case with a new mailbox), so this folder cannot be used as a reliable method of determining which mailboxes exist on the system. Here’s an example of what might be in a mailbox folder.
Using Asterisk As a Standalone Voicemail Server In a traditional telecom environment, the voicemail server was typically a standalone unit (provided either as a separate server altogether, or as an add-in card to the system). Very few PBXs had fully integrated voicemail (in the sense that voicemail was an integral part of the PBX rather than a peripheral device). Asterisk is quite capable of serving as a standalone voicemail system. The two most common reasons one might want to do this are: 1.
Figure 8-1. Simplified SIP enterprise environment Instead you can statically define an entry for each mailbox in the voicemail server’s sip.conf file, indicating where the message notifications are to be sent. Rather than defining the address of each endpoint, however, you can have the voicemail server send all messages to the proxy, which will handle the relay of the message notifications to the appropriate endpoints.
Note that Asterisk’s dynamic realtime will not work with this configuration, as a peer’s information is only loaded into memory when there is an actual call involving that peer. Since message notification is not a call as far as Asterisk is concerned, using dynamic realtime will not allow message waiting to happen for any peers not registered to Asterisk. You will not want to implement this unless you have prototyped the basic operation of the solution.
The voicemail server will need an extensions.
The following is not a detailed explanation of how to configure SMDI for Asterisk, but rather an introduction to the concepts, with some basic examples. If you are planning on implementing SMDI, you will need to write some complex dialplan logic and have a good understanding of how to interconnect systems via serial connections. SMDI is enabled in Asterisk by the use of two options in the [general] section of the voicemail.
Conclusion While the Asterisk voicemail system is quite old in terms of Asterisk code, it is nevertheless a powerful application that can (and does) compete quite successfully with expensive, proprietary voicemail systems.
CHAPTER 9 Internationalization David Duffett I traveled a good deal all over the world, and I got along pretty good in all these foreign countries, for I have a theory that it’s their country and they got a right to run it like they want to. —Will Rogers Telephony is one of those areas of life where, whether at home or at work, people do not like surprises.
Quite a few of the chapters in this book contain information that will help you internationalize* or (perhaps more properly) localize your Asterisk implementation. The purpose of this chapter is to provide a single place where all aspects of the changes that need to be made to your Asterisk-based telephone system in this context can be referenced, discussed, and explained.
really fundamental differences in order to throw light on the next explanation, which covers the settings we might need to change on devices external to Asterisk, such as IP phones. Have you ever considered the fact that an analog phone is a totally dumb device (we know that a basic model is very, very cheap) that needs to connect to an intelligent network (the PSTN), whereas an IP phone (e.g.
usually dial the IP address of the other phone just by using the * key for the dots in the address. Figure 9-2 points to the fact that on an IP phone, we are responsible for setting all of the tones that the network would have provided in the old days. This can be done in one of (at least) two ways. The first is to configure the tones provided by the IP phone on the device’s own web GUI.
The prior discussion of IP phone configuration also applies to any analog telephone adaptors (ATAs) you plan to use—specifically, to those supporting an FXS interface. In addition, you may need to specify some of the electrical characteristics of the telephony interface, like line voltage and impedance, together with the caller ID format that will work with local phones.
Figure 9-3. A balun Analog connections vary massively from place to place—you will know what kind of connector is used in your locality. The important thing to remember is that the analog line is only two wires, and these need to connect to the middle two pins of the RJ11 plug that goes into the Digium card—the other end is the local one. Figure 9-4 shows the plug used in the UK, where the two wires are connected to pins 2 and 5. Figure 9-4.
a primary rate interface (PRI), this will be a T1 in North America, a J1 in Japan, or an E1 in pretty much the rest of the world. Once you have established the type of PRI connection the telco has given you, there are some further details that you will require in order to properly configure DAHDI and Asterisk (e.g., whether the connection is ISDN or a CAS-based protocol). Again, you will find these in Chapter 7.
The /etc/dahdi/system.conf file uses the hash symbol (#) to indicate a comment instead of a semicolon (;) like the files in /etc/asterisk/. Although it is possible to load a number of different tone sets (you can see all the sets of tones in detail in zonedata.c) and to switch between them, in most practical situations you will only need: loadzone=uk defaultzone=uk # to load the tone set # to default DAHDI to using that set …or whichever tones you need for your region.
The relationship between Linux, DAHDI, and Asterisk (and therefore /etc/dahdi/system.conf and /etc/asterisk/chan_dahdi.conf) is shown in Figure 9-5. Figure 9-5. The relationship between Linux, DAHDI, and Asterisk Asterisk With everything set at the Linux level, we now only need to configure Asterisk to make use of the channels we just enabled at the Linux level and to customize the way that Asterisk interprets and generates information that comes in from, or goes out over, these channels.
Again, Asterisk defaults to the North American caller ID format (no entries in /etc/ asterisk/chan_dahdi.conf describe this, it’s just the default), and in order to change it we will need to make some entries that describe the technical details of the caller ID system.
The default directory used is /var/lib/asterisk/sounds/en, so how do you change that? There are two ways. One is to set the language in the channel configuration file that calls are arriving through using the language directive. For example, the line: language=en_UK placed in chan_dahdi.conf, sip.
ordered month, day, year and times are specified in 12-hour clock format (e.g., 2:54 P.M.). In contrast, in the UK, dates are ordered day, month, year and times are often specified in 24-hour clock format (14:54 hrs)—although some people in the UK prefer 12-hour clock format, so we will cover that too. Since all these things are connected to voicemail, you would be right to guess that we configure it in /etc/asterisk/voicemail.conf—specifically, in the [zonemessages] section of the file.
UK24=Europe/London|'vm-received' q 'digits/at' H N 'hours' UK12=Europe/London|'vm-received' Q 'digits/at' IMp These zones not only specify a time, but also dictate the way times and dates are ordered and read out. Having created these zones, we can go to the voicemail context part of voicemail.conf to associate the appropriate mailboxes with the correct zones: [default] 4001 => 1234,Russell Bryant,rb@shifteight.org,,|tz=central 4002 => 4444,David Duffett,dd@shifteight.
Conclusion—Easy Reference Cheat Sheet As you can now see, there are quite a few things to change in order to fully localize your Asterisk-based telephone system, and not all of them are in the Asterisk, or even DAHDI, configuration—some things need to be changed on the connected IP phones or ATAs themselves. Before we leave the chapter, have a look at Table 9-1: a cheat sheet for what to change and where to change it, for your future reference. Table 9-1.
CHAPTER 10 Deeper into the Dialplan For a list of all the ways technology has failed to improve the quality of life, please press three. —Alice Kahn Alrighty. You’ve got the basics of dialplans down, but you know there’s more to come. If you don’t have Chapter 6 sorted out yet, please go back and give it another read. We’re about to get into more advanced topics.
Download from Wow! eBook When Asterisk encounters an expression in a dialplan, it replaces the entire expression with the resulting value. It is important to note that this takes place after variable substitution. To demonstrate, let’s look at the following code*: exten => 321,1,Set(COUNT=3) same => n,Set(NEWCOUNT=$[${COUNT} + 1]) same => n,SayNumber(${NEWCOUNT}) In the first priority, we assign the value of 3 to the variable named COUNT.
expr1 & expr2 This operator (called “and”) returns the evaluation of expr1 if both expressions are true (i.e., neither expression evaluates to an empty string or zero). Otherwise, it returns zero. expr1 {=, >, >=, <, <=, !=} expr2 These operators return the results of an integer comparison if both arguments are integers; otherwise, they return the results of a string comparison. The result of each comparison is 1 if the specified relation is true, or 0 if the relation is false.
This would have assigned the variable TEST to the string “2+1”, instead of the value 3. In order to remedy that, we would put spaces around the operator, like so: exten => 234,1,Set(TEST=$[2 + 1]) This is no longer necessary in current versions of Asterisk, as the expression parser has been made more forgiving in these types of scenarios. However, for readability’s sake, we still recommend including the spaces around your operators.
exten => 123,1,Set(TEST=example) same => n,SayNumber(${LEN(${TEST})}) This example will first evaluate $TEST as example. The string “example” is then given to the LEN() function, which will evaluate as the length of the string, 7. Finally, 7 is passed as an argument to the SayNumber() application. Let’s look at another simple example. If we wanted to set one of the various channel timeouts, we could use the TIMEOUT() function.
Either of the destinations may be omitted, but not both. If the omitted destination is to be followed, Asterisk simply goes on to the next priority in the current extension.
exten => iguanas,1,Playback(office-iguanas) same => n,Hangup() By changing the value assigned to TEST in the first line, you should be able to have your Asterisk server play a different greeting. Let’s look at another example of conditional branching.
Time-Based Conditional Branching with GotoIfTime() Another way to use conditional branching in your dialplan is with the GotoIfTime() application. Whereas GotoIf() evaluates an expression to decide what to do, GotoIf Time() looks at the current system time and uses that to decide whether or not to follow a different branch in the dialplan. The most obvious use of this application is to give your callers a different greeting before and after normal business hours.
months This is a list of one or more months of the year. The months should be written as jan-apr for a range, and separated with ampersands when wanting to include nonsequential months, such as jan&mar&jun. You can also combine them like so: jan-apr&jun&oct-dec. If you wish to match on all possible values for any of these arguments, simply put an * in for that argument.
Macros Macros§ are a very useful construct designed to avoid repetition in the dialplan. They also help in making changes to the dialplan. To illustrate this point, let’s look at our sample dialplan again.
Macro definitions look a lot like contexts. (In fact, you could argue that they really are small, limited contexts.) You define a macro by placing macro- and the name of your macro in square brackets, like this: [macro-voicemail] Macro names must start with macro-. This distinguishes them from regular contexts. The commands within the macro are built almost identically to anything else in the dialplan; the only limiting factor is that macros use only the s extension.
[macro-voicemail] exten => s,1,Dial(${JOHN},10) same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail) same => n(unavail),VoiceMail(${MACRO_EXTEN}@default,u) same => n,Hangup() same => n(busy),VoiceMail(${MACRO_EXTEN}@default,b) same => n,Hangup() Using Arguments in Macros Okay, now we’re getting closer to having the macro the way we want it, but we still have one thing left to change: we need to pass in the channel to dial, as it’s currently still hardcoded for ${JOHN} (remember that we defined the va
Since we know how to use dialplan functions now as well, here is another way of controlling which voicemail prompt (unavailable vs. busy) is played to the caller.
same => n(busy),VoiceMail(101@default,b) same => n,Hangup() If we were going to convert this to be used for a subroutine, it might look like this: [subVoicemail] exten => start,1,Dial(${JOHN},10) same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail) same => n(unavail),VoiceMail(101@default,u) same => n,Hangup() same => n(busy),VoiceMail(101@default,b) same => n,Hangup() Not much of a change, right? All we’ve altered in this example is the context name, from [macro-voicemail] to [subVoicemail], and th
Using Arguments in Subroutines The ability to use arguments is one of the major features of using Macro() or GoSub(), because it allows you to abstract out code that would otherwise be duplicated across your dialplan. Without the need to duplicate the code, we can better manage it, and we can easily add functionality to large numbers of users by modifying a single location. You are encouraged to move code into this form whenever you find yourself creating duplicate code.
Returning from a Subroutine Unlike Macro(), the GoSub() dialplan application does not return automatically once it is done executing. In order to return from whence we came, we need to use the Return() application. Now that we know how to call a subroutine and pass arguments, we can look at an example where we might need to return from the subroutine.
exten => start,1,VoiceMail(${ARG1}@${ARG2},${ARG3}) same => n,Hangup() In this version we’ve made just the one change: Return() to Return(${DIALSTATUS}).
box, like we’ve done for other portions of the dialplan. We’ll be building the dialplan to match the time starts and stops described in Figure 10-1. Figure 10-1. Time delayed dialing with local channels First we need to call three Local channels, which will all execute different parts of the dialplan.
Time period (in seconds) channel_1 channel_2 channel_3 25 30 Hangup() 35 40 In this table, we can see that channel_1 started dialing location SIP/0000FFFF0001 immediately and waited for a period of 20 seconds. After 20 seconds, that Local channel hung up. Our channel_2 waited for 10 seconds prior to dialing the endpoint DAHDI/ g0/14165551212.
Additional scenarios and information about Local channels and the modifier flags (/n, /j, /m, /b) are available at https://wiki.asterisk.org/wiki/display/AST/Local+Chan nel. If you will be making any sort of regular use of Local channels, that is a very important document to read. Using the Asterisk Database (AstDB) Having fun yet? It gets even better! Asterisk provides a powerful mechanism for storing values called the Asterisk database (AstDB).
exten => 456,1,Set(DB(test/count)=1) same => n,Set(COUNT=${DB(test/count)}) same => n,SayNumber(${COUNT}) You may also check the value of a given key from the Asterisk command line by running the command database get . To view the entire contents of the AstDB, use the database show command. Deleting Data from the AstDB There are two ways to delete data from the Asterisk database. To delete a key, you can use the DB_DELETE() application.
same => n(continue),NoOp() same => n,SayNumber(${COUNT}) same => n,Set(COUNT=$[${COUNT} + 1]) Now that we’ve incremented COUNT, let’s put the new value back into the database.
Handy Asterisk Features Now that we’ve gone over some more of the basics, let’s look at a few popular functions that have been incorporated into Asterisk. Zapateller() Zapateller() is a simple Asterisk application that plays a special information tone at the beginning of a call, which causes auto-dialers (usually used by telemarketers) to think that the line has been disconnected.
Also note that because the user needs to be able to transfer the calls to the parking lot extension, you should make sure you’re using the t and/or T options to the Dial() application. So, let’s create a simple dialplan to show off call parking: [incoming] include => parkedcalls exten => 103,1,Dial(SIP/Bob,,tT) exten => 104,1,Dial(SIP/Charlie,,tT) To illustrate how call parking works, say that Alice calls into the system and dials extension 103 to reach Bob.
the conference room (as defined in meetme.conf), a set of options, and the password the user must enter to join this conference. Let’s set up a simple conference using room 600, the i option (which announces when people enter and exit the conference), and a password of 54321: exten => 600,1,MeetMe(600,i,54321) That’s all there is to it! When callers enter extension 600, they will be prompted for the password. If they correctly enter 54321, they will be added to the conference.
CHAPTER 11 Parking and Paging I don’t believe in angels, no. But I do have a wee parking angel. It’s on my dashboard and you wind it up. The wings flap and it’s supposed to give you a parking space. It’s worked so far. —Billy Connolly This chapter will focus on two important aspects of a PBX system: parking calls to allow them to be answered from a location different from where they were originally answered, and paging, which allows the announcement of who the call is for and how it can be retrieved.
signals in the audio channel triggered by the users dialing the required digits on their dialpads).* Transfers on SIP channels (for example from a SIP telephone) can be handled using the capabilities of the phone itself, and won’t be affected by anything in the features.conf file. The [general] section In the [general] section of features.conf, you can define options that fine-tune the behavior of the park and transfer features in Asterisk. These options are listed in Table 11-1. Table 11-1. features.
a Option Value/Example Notes parkedcallhangup caller Controls which side of a call has the ability to execute a DTMF-based hangup in the call that results from picking up a parked call. Valid options include callee, caller, both, or no. The default is no. parkedcallrecording caller Controls which side of a call has the ability to initiate a DTMF-based onetouch recording in the call that results from picking up a parked call. Valid options include callee, caller, both, or no. The default is no.
Handling Timed-Out Parked Calls with the comebacktoorigin Option This option configures the behavior of call parking when the parked call times out (see the parkingtime option). comebacktoorigin can have one of two values: yes (default) When the parked call timeout is exceeded, Asterisk will attempt to send the call back to the peer that parked this call. If the channel is no longer available to Asterisk, the caller will be disconnected.
The [featuremap] Section This section allows you to define specific DTMF sequences, which will trigger various features on channels that have been bridged via options in the Dial() or Queue() application. The options are detailed in Table 11-2. Table 11-2. features.
3. Defining which channel the feature will be activated on, and (optionally) which participant is allowed to activate the feature (the default is to allow both channels to use/activate this feature). 4. Giving the name of the application that this map will trigger, and its arguments. 5. Providing an optional music on hold (MOH) class to assign to this feature (which the opposite channel will hear when the application is executing). If you do not define any MOH class, the caller will hear only silence.
Inheriting Channel Variables Channel variables are always associated with the original channel that set them, and are no longer available once the channel is transferred. In order to allow channel variables to follow the channel as it is transferred among the system, channel variable inheritance must be employed. There are two modifiers that can allow the channel variable to follow the channel: single underscore and double underscore.
Download from Wow! eBook If you want to specify a custom key mapping to a feature in an application map grouping, simply follow the => with the key mapping you want. If you do not specify a key mapping, the default key map for that feature will be used (as found in the [featuremap] section). Regardless of whether you want to assign a custom key mapping or not, the => operator is required.
better for each successive page to assign the next slot, since you will often have more than one call parked at a time. Your users will get used to listening carefully to the actual parking lot number (instead of just always dialing 701), and this will minimize the chance of people accidentally retrieving the wrong call on a busy system. If you are using parking, you are probably also going to need a way to announce the parked calls so that the intended parties know how to retrieve them.
Table 11-3. Page() options Option Description Discussion d Enables full-duplex audio Sometimes referred to as “talkback paging,” the use of this option implies that the equipment that receives the page has the ability to transmit audio back at the same time as it is receiving audio. Generally, you would not want to use this unless you had a specific need for it. i Ignores attempts to forward the call You would normally want this option enabled.
is connected to a paging interface such as a Bogen UTI1,§ which then connects to the paging amplifier.‖ In your dialplan, paging to an external amplifier would look like a simple Dial() to the device that is connected to the paging equipment. For example, if you had an ATA configured in sip.
Beyond a certain size, your Asterisk system will be unable to page multiple sets. For example, in an office with 200 telephones, using SIP to page every set would not be possible; the traffic and CPU load on your Asterisk server would simply be too much. In cases like this, you should be looking at either multicast paging or external paging.
Fortunately, many of these sets support IP multicast, which is a far better way to send a page to multiple sets (read on for details). Still, if you only have a few phones on your system and they are all from the same manufacturer, SIP-based paging could be the simplest, so we don’t want to scare you off it completely.
Multicast Paging on Cisco SPA Telephones The multicast paging feature on Cisco SPA phones is a bit strange, but once configured it works fine. The trick of it is that the address you put into the phone is not the multicast address that the page is sent across, but rather a sort of signaling channel. What we have found is that you can make this address the same as the multicast address, but simply use a different port number. The dialplan looks like this: exten => *724,1,Page(MulticastRTP/linksys/239.0.0.
this is fairly simple to accomplish. When you call the Page() application, you simply specify the various resources you want to page, separated by the & character, and they will all be included in the conference that the Page() application creates. Bringing it all together At this point you should have a list of the various channel types that you want to page.
zone controller answers, and then an additional digit is sent to select which zone the page is to be sent to. Most zone controllers will allow for a page to all zones, in addition to combining zones (for example, a page to both the new and used car sales departments). You could also have separate extensions in the dialplan going to separate ATAs (or groups of telephones), but this may prove more complicated and expensive than simply purchasing a paging controller that is designed to handle this.
CHAPTER 12 Internet Call Routing There ain’t no such thing as a free lunch (TANSTAAFL). —Robert Heinlein One of the attractions of VoIP is the concept of avoiding the use of the PSTN altogether, and routing all calls directly between endpoints using the Internet at little or no cost. While the technology to do this has been around for some time, the reality is that most phone calls still cost money—even those that are routed across VoIP services.
handled through numerical IP addresses, it can be very helpful to associate a name (such as www.google.com) with what may in fact be multiple IP addresses. In the case of VoIP, the use of a domain name can take something like 100@192.168.1.1 (extension@server) and make it available as leif@shifteight.org (which looks so much sexier on a business card). The SIP URI A SIP URI generally looks like sip:endpoint@domain.tld. Depending on your SIP client, you may be able to dial a SIP URI as endpoint@domain.
(SIP being one of them). If you want to support SIP lookups on your domain, you will require a relevant SRV record in order to properly respond. When a SIP connection does a lookup on leif@shifteight.org, for the purposes of SIP, the SRV record can respond that the requested service (SIP) is actually found on the server pbx.shifteight.org (or possibly even on a completely different domain, such as pbx.tothemoon.net).
Any SIP requests to your domain will be referred to your Asterisk server, which will be responsible for handling incoming SIP connections.‖ If your dialplan does not understand the name/resource/endpoint portion of the SIP URI, calls will fail. This means that if you want to be able to offer resources in your Asterisk system by name, you will need relevant dialplan entries.
A dialplan entry on the pbx.shifteight.org system might look like this: [unauthenticated] exten => leif,1,Goto(PublicExtensions,100,1) exten => jim,1,Goto(PublicExtensions,101,1) exten => tilghman,1,Goto(PublicExtensions,102,1) exten => russell,1,Goto(PublicExtensions,103,1) This is by far the simplest way to implement name dialing, but it is also complex to maintain, especially in systems with hundreds of users.
If the call does not explicitly match our named extensions, the pattern match will be utilized. Our pattern match of _[A-Za-z0-9]. matches any string starting with an alphanumeric character followed by one or more other characters. The incoming string needs to be made safe, so we utilize the FILTER() function to remove nonalphanumeric characters, and assign the result to the FilteredExtension channel variable.
We’ve written this as a subroutine, which is invoked something like this: ; where 'name' is the username as found in the email address GoSub(subEmailToExtensionLookup,start,1(name)) The subroutine looks like this: [subEmailToExtensionLookup] exten => start,1,Verbose(2,Checking for user in voicemail.conf) same => n,Set(LOCAL(FilteredExtension)=${FILTER(a-z0-9,${ARG1})}) same => n,Set(LOCAL(Result)=${SHELL(grep "${LOCAL(FilteredExtension)}@" /etc/asterisk/voicemail.
If ${Result} is not null, the next steps will clean up ${Result} in order to extract the extension number* of the user with the name passed in ${ARG1}: Set(LOCAL(ExtensionToDial)=${CUT(${LOCAL(Result)},=,1)}) The CUT() function will use the = symbol as the field delimiter and will assign the value from the first field found in ${Result} to the new variable ExtensionToDial.
Table 12-2. NameMapping table a Name Extension Context leif 100 publicExtensions leif.madsen 100 publicExtensions lmadsen 100 publicExtensions jim 101 publicExtensions reception 0 Servicesa voicemail *98 Services Make sure this context exists on your system. We believe that having a separate table that only handles name-to-extension/context mapping is the most useful solution, since this table can be used to handle more than just users with telephone sets.
Details on how to handle all of this in your dialplan are beyond the scope of this book. Suffice it to say that in your dialplan you will still need to handle the values that your subroutine creates or assigns. Dialing SIP URIs from Asterisk Asterisk can dial a SIP URI as easily as any other sort of destination, but it is the endpoint (namely, your telephone) that is ultimately going to shoulder the burden of composing the address, and there lies the difficulty.
ENUM and E.164 Although the SIP protocol really doesn’t think in terms of phone numbers, the reality is that phone numbers are not going away any time soon, and if you want to properly integrate a VoIP system with as many telephone networks as possible, you’re going to need to handle the PSTN in some way. ENUM maps telephone numbers onto the Domain Name System (DNS). In theory, ENUM is a great idea.
In the UK, you might need something more like this: _0[123789]XXXXXXXXX _0[123789]XXXXXXXX And in Australia, your dialplan might have these pattern matches: _NXXXXXXX _0XXXXXXXXX Please don’t just copy and paste these pattern matches into your dialplan. The peculiarities of regional dialplans are tricky, and change constantly. One important item that needs to be carefully considered is the region-specific number for emergency calling, as discussed in “Emergency Dialing” on page 154.
ENUM has not taken off. The reasons appear to be mostly political in nature. The problem stems from the fact that there is no one organization that controls numbering on the PSTN the way that IANA does for the Internet. Since no one entity has a clear mandate for managing E.164 numbers globally, the challenge of maintaining an accurate and authoritative database for ENUM has proved elusive.
An ENUM lookup in the dialplan might look like this: exten => _X.,1,Set(CurrentExten=${FILTER(0-9,${EXTEN})}) same => n,Set(LookupResult=${ENUMLOOKUP(${CurrentExten},sip,,,e164.arpa)}) same => n,GotoIf($[${EXISTS(${LookupResult})}]?HaveLocation,1) same => n,Set(LookupResult=${ENUMLOOKUP(${CurrentExten},sip,,,e164.org)}) same => n,GotoIf($[${ISNULL(${LookupResult})}]?NormalCall,1:HaveLocation,1) exten => HaveLocation,1,Verbose(2,Handle dialing via SIP URI returned) exten => ...
Got ISN? The heart of the freenum.org concept is the ITAD Subscriber Number (ISN). The ISN is a numeric string that is composed of an extension number on your system, an asterisk character separator (*),‖ and a number that is unique to your organization called an IP Telephony Administrative Domain (ITAD) number. The advantage of the ISN is that it can be dialed from any telephone.
There are many other numbering schemes that have been created as a result of an RFC. Other IANA-managed numbers include MAC addresses—specifically, the Organizationally Unique Identifier (OUI) portion of the MAC addressing space. Several years ago, a protocol named TRIP (Telephony Routing over IP) was created. While this protocol never took off, and is unlikely to see any future growth, it did offer us one incredibly useful thing: the ITAD.
Your application will be reviewed by a Real Human Being™, and within a few days you should be assigned an ITAD by IANA. A few days later, you will also receive information for your freenum.org account (there is currently a simple review process to ensure that bots and spammers don’t abuse the system). You will then need to log onto the freenum.org site and define the parameters for your ITAD. Create a DNS Entry for Your ITAD In the top-right corner of the freenum.org site, you will see a Sign in here link.
John Todd notes: “For those sites which have extremely complex configurations or geographically diverse offices with different SIP servers handling different prefixes (for instance: 12xxx goes to the Asterisk server in France, 13xxx to the Asterisk server in Germany, and so on) then there are more sophisticated methods where you run your own delegated zone out of the freenum.org domain, but those are outside the scope of this book but can be learned about on the freenum.org site.
[subFreenum] exten => start,1,Verbose(2,Performing ISN lookup) same => n,Set(ISN=${FILTER(0-9*,${ARG1})}) same => n,Set(Result=${ENUMLOOKUP(${ISN},sip,s,,freenum.
Our code for performing the lookup then looks like this: exten => start,n,Set(Result=${ENUMLOOKUP(${ISN},sip,s,,freenum.org)}) Following the lookup and storing the result in the ${Result} channel variable, our subroutine will verify whether we received a result or not: exten => start,n,GotoIf($[${EXISTS(${Result})}]?call,1:no_result,1) If no result is received, the call will be handled in the no_result extension.
Toll Fraud Toll fraud is by far the biggest risk to your phone system in terms of the potential for ruinous cost. It is not unheard of for fraudsters to rack up tens of thousands of dollars in stolen phone calls over the course of a few days. Toll fraud is not a new thing, having existed prior to VoIP; however, the enabling nature of VoIP means that it is easier for fraudsters to take advantage of unsecured systems.
Spam over Internet Telephony (SPIT) VoIP spam has not yet taken off, but rest assured, it will. Spammers all over the world are drooling at the prospect of being able to freely assault anyone and everyone with an Internet-enabled phone system. Like email, VoIP entails a certain level of trust, in that it assumes that every phone call is legitimate. Unfortunately, as with email spam, it only takes a few bad apples to spoil things for the rest of us.
Security Is an Ongoing Process In contrast to previous editions, throughout this book we have tried to provide examples and best practices that take security into consideration at all stages. Whatever you are working on, you should be thinking about security. While implementing good security requires more design, development, and testing effort, it will save you time and money in the long run. Most security holes happen as a result of something that was hastily implemented and wasn’t locked down later.
Download from Wow! eBook
CHAPTER 13 Automatic Call Distribution (ACD) Queues An Englishman, even if he is alone, forms an orderly queue of one. —George Mikes Automatic Call Distribution (ACD), or call queuing, provides a way for a PBX to queue up incoming calls from a group of users: it aggregates multiple calls into a holding pattern and assigns each call a rank that determines the order in which that call should be delivered to an available agent (typically, first in first out).
We’ve all been frustrated by poorly designed and managed queues: enduring hold music from a radio that isn’t in tune, mind-numbing wait times, and pointless messages that tell you every 20 seconds how important your call is, despite that fact that you’ve been waiting for 30 minutes and have heard the message so many times you can quote it from memory. From a customer service perspective, queue design may be one of the most important aspects of your telephone system.
look into how to create a dialplan that allows us to dynamically add and remove queue members (as well as pause and unpause them). The first step is to create your queues.conf file in the /etc/asterisk configuration directory: $ cd /etc/asterisk/ $ touch queues.conf Populate it with the following configuration, which will create two queues named [sales] and [support].
was wrapping up a call from the support queue might still get a call from the sales queue. This option should also always be set to yes (the default). The next section, [StandardQueue] is the template we’ll apply to our sales and support queues (we declared it a template by adding (!)). We’ve defined the musicclass to be the default music on hold, as configured in the musiconhold.conf file. The strategy we’ll employ is rrmemory, which stands for Round-Robin with Memory.
Once you’ve finished configuring your queues.conf file, you can save it and reload the app_queue.so module from your Asterisk CLI: $ asterisk -r *CLI> module reload app_queue.so -- Reloading module 'app_queue.so' (True Call Queueing) Then verify that your queues were loaded into memory: localhost*CLI> queue show support has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.
You don’t join the queue at this point, as there are no agents in the queue to answer calls. Because we have joinempty=no and leavewhenempty=yes configured in queues.conf, callers will not be placed into the queue. (This would be a good opportunity to experiment with the joinempty and leavewhenempty options in queues.conf to better understand their impact on queues.
Adding a queue member to the support queue can be done with the queue add member command: *CLI> queue add member SIP/0000FFFF0001 to support Added interface 'SIP/0000FFFF0001' to queue 'support' A query of the queue will verify that our new member has been added: *CLI> queue show support support has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.
Controlling Queue Members with Dialplan Logic In a call center staffed by live agents, it is most common to have the agents themselves log in and log out at the start and end of their shifts (or whenever they go for lunch, or to the bathroom, or are otherwise not available to the queue).
In short, agents who are not sitting at their desks and planning to be available to take calls in the next few minutes should log out. Pause/unpause should only be used for brief moments of unavailability (if at all). If you want to use your phone system as a punch clock, there are lots of great ways to do that in Asterisk, but the queue member applications are not the way we would recommend. Let’s build some simple dialplan logic that will allow our agents to indicate their availability to the queue.
; ${UPQMSTATUS}: ; UNPAUSED ; NOTFOUND Automatically Logging Into and Out of Multiple Queues It is quite common for an agent to be a member of more than one queue.
; if there are no queues assigned to this agent we'll handle it in the ; no_queues_available extension same => n,GotoIf($[${ISNULL(${AvailableQueues})}]?no_queues_available,1) same => n,Return() exten => no_queues_available,1,Verbose(2,No queues available for agent ${MemberChannel}) ; *** This should all be on a single line ; playback a message stating the channel has not yet been assigned same => n,Playback(silence/1&channel¬-yet-assigned) same => n,Hangup() [ACD] ; ; Used for logging agents into all co
same => n,Playback(silence/1&channel¬-yet-assigned) same => n,Hangup() ; ------------------------; Used for logging agents out of all configured queues per the AstDB exten => *56,1,Verbose(2,Logging out of multiple queues) ; Because we reused some code, we've placed the duplicate code into a subroutine same => n,GoSub(subSetupAvailableQueues,start,1()) same => n,Set(QueueCounter=1) same => n,Set(WorkingQueue=${CUT(AvailableQueues,^,${QueueCounter})}) same => n,While($[${EXISTS(${WorkingQueue})}]) same =>
You could further refine these login and logout routines to take into account that the AQMSTATUS and RQMSTATUS channel variables are set each time AddQueueMember() and RemoveQueueMember() are used. For example, you could set a flag that lets the queue member know he has not been added to a queue by setting a flag, or even add recordings or text-to-speech systems to play back the particular queue that is producing the problem.
*CLI> queue show support support has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 0s Members: SIP/0000FFFF0001 (dynamic) (Not in use) has taken no calls yet No Callers Notice that even though our phone should be marked as In Use because it is on a call, it does not show up that way when we look at the queue status. This is obviously a problem since the queue will consider this device as available, even though it is already on a call.
The queues.conf File We’ve mentioned the queues.conf file already, but there are many options in this file, and we figured it would be right and proper for us to go over some of them with you. Table 13-1 contains the options available in the [general] section of queues.conf. Table 13-1. Available options for [general] section of queues.
Options Available values Description • random: rings a random interface • rrmemory: rings members in a round-robin fashion, remembering where we left off last for the next caller • linear: rings members in the order specified, always starting at the beginning of the list • wrandom: rings a random member, but uses the members’ penalties as a weight. servicelevel Value in seconds Used in statistics to determine the service level of the queue (calls answered within the service level time frame).
Options Available values Description setinterfacevar yes, no If set to yes, the following channel variables will be set just prior to connecting the caller with the queue member: • MEMBERINTERFACE: the member’s interface, such as Agent/1234 • MEMBERNAME: the name of the member • MEMBERCALLS: the number of calls the interface has taken • MEMBERLASTCALL: the last time the member took a call • MEMBERPENALTY: the penalty value of the member • MEMBERDYNAMIC: indicates whether the member was dyna
Options Available values Description membermacro Name of a macro defined in the dialplan Defines a macro to be executed just prior to bridging the caller and the queue member. announce-frequency Value in seconds Defines how often we should announce the caller’s position and/or estimated hold time in the queue. Set this value to zero to disable. min-announce-frequency Value in seconds Specifies the minimum amount of time that must pass before we announce the caller’s position in the queue again.
Options Available values Description queue-callswaiting Filename of prompt to play If not defined, will play the default value (“calls waiting”). If set to an empty value, the prompt will not be played at all. queue-holdtime Filename of prompt to play If not defined, will play the default value (“The current estimated hold time is”). If set to an empty value, the prompt will not be played at all. queue-minutes Filename of prompt to play If not defined, will play the default value (“minutes”).
Options Available values Description • wrapup: members are considered unavailable if they are currently in the wrapup time after the completion of a call. leavewhenempty paused, pen alty, inuse, ringing, unavailable, invalid, unknown, wrapup Used to control whether callers are kicked out of the queue when members are no longer available to take calls. See joinempty for more information on the assignable values.
The agents.conf File If you’ve browsed through the samples in the ~/src/asterisk-complete/1.8/configs/ directory, you may have noticed the agents.conf file. It may seem tempting, and it has its places, but overall the best way to implement queues is through the use of SIP channels. There are two reasons for this. The first is that SIP channels are the only type that provide true device state information.
Options Available values Description enddtmf Single DTMF character Used in conjunction with endcall, this option defines the DTMF character to be used to end a call. Defaults to *. wrapuptime Value in milliseconds Specifies the amount of time after disconnection of a caller from an agent for which the agent will not be available to accept another call. Used in situations where agents must perform a function after each call (such as entering call details into a log).
Advanced Queues In this section we’ll take a look at some of the finer-grained queue controls, such as options for controlling announcements and when callers should be placed into (or removed from) the queue. We’ll also look at penalties and priorities, exploring how we can control the agents in our queue by giving preference to a pool of agents to answer the call and increase that pool dynamically based on the wait times in the queue.
callers to. This can be done wherever you would normally place your dialplan logic to perform transfers.
Shaw and Danielle Roberts in the sales queue so Kay Madsen is preferred, and penalize James Shaw and Kay Madsen in the billing queue so Danielle Roberts is preferred. Penalizing queue members can be done either in the queues.conf file, if you’re specifying queue members statically, or through the AddQueueMember() dialplan application. Let’s look at how our queues would be set up with static members in queues.conf.
are to be used for servicing callers. Let’s say we have a queue called support, and we have five queue members with various penalties ranging from 1 through 5.
With our rule now loaded into memory, we can modify our dialplan to make use of it.
Table 13-5. Options related to prompt control timing within a queue Options Available values Description announce-frequency Value in seconds Defines how often we should announce the caller’s position and/ or estimated hold time in the queue. Set this value to zero to disable. min-announce-frequency Value in seconds Indicates the minimum amount of time that must pass before we announce the caller’s position in the queue again.
Options Available values Description queue-youarenext Filename of prompt to play If not defined, will play the default value (“You are now first in line”). If set to an empty value, the prompt will not be played at all. queue-thereare Filename of prompt to play If not defined, will play the default value (“There are”). If set to an empty value, the prompt will not be played at all. queue-callswaiting Filename of prompt to play If not defined, will play the default value (“calls waiting”).
We’ll now modify the StardardQueue template to control our announcements: [StandardQueue](!) musicclass=default strategy=rrmemory joinempty=yes leavewhenempty=no ringinuse=no ; ; ; ; ; ; ; template to provide common features play [default] music use the Round Robin Memory strategy do not join the queue when no members available leave the queue when no members available don't ring members when already InUse (prevents multiple calls to an agent) ; -------- Announcement Control -------announce-frequency=30
(lets say 30 seconds), it will appear as if it is being played every 15 seconds, rather than every 45 seconds as may be intended. How many times we announce the hold time to the caller is controlled via the announceholdtime option, which we’ve set to once. Setting the value to yes will announce it every time, and setting to no will disable it. We configure how and when we announce the caller’s estimated remaining hold time via announce-position, which we’ve set to limit.
Of course, we could define a different destination, but the VoiceMail() application is as good as any. Just make sure that if you’re going to send callers to voicemail someone checks it regularly and calls your customers back. Now let’s say we have the scenario where we have set our absolute timeout to 10 seconds, our timeout value for ringing queue members to 5 seconds, and our retry timeout value to 4 seconds.
For joinempty, prior to placing a caller into the queue, all the members are checked for availability using the factors you list as criteria. If all members are deemed to be unavailable, the caller will not be permitted to enter the queue, and dialplan execution will continue at the next priority.
; queues.conf [support](StandardQueue) member => Local/SIP-0000FFFF0001@MemberConnector ; ; ; ; ; pass the technology to dial over and the device identifier, separated by a hyphen. We'll break it apart inside the MemberConnector context. Notice how we passed the type of technology we want to call along with the device identifier to the MemberConnector context. We’ve simply used a hyphen (although we could have used nearly anything as a separator argument) as the field marker.
; queues.conf [support](StandardQueue) member => Local/SIP-0000FFFF0001@MemberConnector,,,SIP/0000FFFF0001 Only SIP channels are capable of sending back reliable device state information, so it is highly recommended that you use only these channels when using Local channels as queue members. You can also use the AddQueueMember() and RemoveQueueMember() applications to add members to and remove members from a queue, just like with any other channel.
; assign the first field of QueueMember to Technology using the hyphen separator same => n,Set(Technology=${CUT(QueueMember,-,1)}) ; assign the second field of QueueMember to Device using the hyphen separator same => n,Set(Device=${CUT(QueueMember,-,2)}) ; Increase the value of the group inside the queue_members category by one same => n,Set(GROUP(queue_members)=${Technology}-${Device}) ; Check if the group@category is greater than 1, and, if so, return Congestion() ; (too many channels) ; ; *** This line s
queue_log_to_file Controls whether the queue log should be written to a file even when a real time backend is present. Valid values are yes or no (defaults to no). queue_log_name Controls the name of the queue log. The default is queue_log. The queue log is a pipe-separated list of events.
Table 13-9. Events in the Asterisk queue log Event Information provided ABANDON Written when a caller in a queue hangs up before his call is answered by an agent. Three parameters are provided for ABANDON: the position of the caller at hangup, the original position of the caller when entering the queue, and the amount of time the caller waited prior to hanging up. ADDMEMBER Written when a member is added to the queue.
a Event Information provided PENALTY Written when a member’s penalty is modified. The penalty can be changed through several means, such as the QUEUE_MEMBER_PENALTY() function, through using Asterisk Manager Interface, or the Asterisk CLI commands. REMOVEMEMBER Written when a queue member is removed from the queue. The bridge channel field will contain the name of the member removed from the queue.
CHAPTER 14 Device States Out of clutter, find simplicity. —Albert Einstein It is often useful to be able to determine the state of the devices that are attached to a telephone system. For example, a receptionist might require the ability to see the statuses of all the people in the office in order to determine whether somebody can take a phone call. Asterisk itself needs this same information.
Virtual device Description Park: The state of a spot in a call parking lot. The state information will reflect whether or not a caller is currently parked at that extension. More information about call parking in Asterisk can be found in “Parking Lots” on page 228. Calendar: Calendar state. Asterisk will use the contents of the named calendar to set the state to available or busy. More information about calendar integration in Asterisk can be found in Chapter 18.
Download from Wow! eBook Chapter 20 discusses the Asterisk Manager Interface (AMI). The Get Var manager action can be used to retrieve device state values in an external program. You can use it to get the value of either a normal variable or a dialplan function, such as DEVICE_STATE().
Figure 14-2. Extension state mappings Typically, hints are simply defined along with the rest of the extension.
[phones] exten => 7001,hint,SIP/0004F2060EB4 When core show hints is executed at the Asterisk CLI, the following output is presented when the device is currently in use: *CLI> core show hints -= Registered Asterisk Dial Plan Hints =7001@phones : SIP/0004F2060EB4 State:InUse ---------------- 1 hints registered Watchers 0 In addition to showing you the state of the extension, the output of core show hints also provides a count of watchers.
SIP Presence Asterisk provides the ability for devices to subscribe to extension state using the SIP protocol. This functionality is often referred to as BLF (Busy Lamp Field).* Asterisk Configuration To get this working, hints must be defined in /etc/asterisk/extensions.conf (see “Hints” on page 303 for more information on configuring hints in the dialplan). Additionally, there are some important options that must be set in the configuration file for the SIP channel driver, which is /etc/asterisk/sip.
subscribecontext Allows you to set a specific context for subscriptions. Without this set, the context defined by the context option will be used. This option may be set either in the [general] section or in peer-specific sections of sip.conf. notifyringing Controls whether or not a notification will be sent when an extension goes into a ringing state. This option is set to yes by default. It only has an effect on subscriptions that use the dialog-info event package.
Custom device states can be used as a way to directly control the state shown on a device that has subscribed to the state of an extension. Just map an extension to a custom device state using a hint in the dialplan: exten => example,hint,Custom:example An Example There are a number of interesting use cases for custom device states. In this section we will build an example that implements a custom “do not disturb” (DND) button on a SIP phone.
Example 14-1 shows the full example as it would appear in /etc/asterisk/extensions.conf. Example 14-1. Custom “do not disturb” functionality using custom device states ; ; A hint so a phone can use BLF to signal the DND state. ; exten => DND_7015,hint,Custom:DND_7015 ; ; An extension to dial when the user presses the custom DND ; key on his phone. This will toggle the state and will result ; in the light on the phone turning on or off.
To accomplish distributed device state, some sort of messaging mechanism must be used for the servers to communicate with each other. Two such mechanisms are supported as of Asterisk 1.8: AIS and XMPP. Using OpenAIS The Application Interface Specification (AIS) is a standardized set of messaging middleware APIs. The definition for the APIs is provided by the Service Availability Forum.
After running the configure script, run the menuselect tool to ensure that Asterisk has been told to build the res_ais module (this module can be found in the Resource Modules section of menuselect): $ make menuselect Finally, compile and install Asterisk: $ make $ sudo make install This is a pretty quick and crude set of instructions for compiling and installing Asterisk. For a much more complete set of instructions, please see Chapter 3.
To get started with testing out basic OpenAIS connectivity, try starting the aisexec application in the foreground and watching the output: $ sudo aisexec -f For example, if you watch the output of aisexec on the first node while you bring up the second node, you should see output that reflects that the cluster now has two connected nodes: Nov 13 06:55:30 corosync Nov 13 06:55:30 corosync Nov 13 06:55:30 corosync Nov 13 06:55:30 corosync Nov 13 06:55:30 corosync Nov 13 06:55:30 corosync Nov 13 06:55:30 cor
=== --------------------------------------------------------=== ============================================================= Another useful Asterisk CLI command provided by the res_ais module is used to list the members of the AIS cluster: *CLI> ais clm show members ============================================================= === Cluster Members ========================================= ============================================================= === === -------------------------------------------------
If you would like to dive deeper into the processing of distributed device state changes, there are some useful debug messages that can be enabled. First, enable debug on the Asterisk console in /etc/asterisk/logger.conf. Then, enable debugging at the Asterisk CLI: *CLI> core set debug 1 With the debug output enabled, you will see some messages that show how Asterisk is processing each state change.
Asterisk has the ability to use XMPP PubSub to distribute device state information. One of the nice things about using XMPP to accomplish this is that it works very well for geographically distributed Asterisk servers. Installation To distribute device states using XMPP, you will need an XMPP server that supports PubSub. One such server that has been successfully tested against Asterisk is Tigase. The Tigase website has instructions for installing and configuring the Tigase server.
This is a pretty quick and crude set of instructions for compiling and installing Asterisk. For a much more complete set of instructions, please see Chapter 3. Creating XMPP accounts Unfortunately, Asterisk is currently not able to register new accounts on an XMPP server. You will have to create an account for each server via some other mechanism. The method we used while testing was to use an XMPP client such as Pidgin to complete the account registration process.
serverhost = jabber.shifteight.org pubsub_node = pubsub.jabber.shifteight.org username = server2@jabber.shifteight.org/astvoip2 secret = mypassword distribute_events = yes status = available usetls = no usesasl = yes buddy = server1@jabber.shifteight.org/astvoip1 Testing To ensure that everything is working properly, start by doing some verification of the jabber.conf settings on each server. There are a couple of relevant Asterisk CLI commands that can be used here.
Next, start Asterisk on the second server and run jabber show buddies on that server. The output will contain more information, since the second server will see the first server online: *CLI> jabber show buddies Jabber buddy lists Client: server2@jabber.shifteight.org/astvoip2 Buddy: server1@jabber.shifteight.org Resource: astvoip1 node: http://www.asterisk.org/xmpp/client/caps version: asterisk-xmpp Jingle capable: yes Status: 1 Priority: 0 Buddy: server1@jabber.shifteight.
these applications is the MeetMe() application. The SLA applications come with the same module as the MeetMe() application, so you must install the app_meetme module. You can check at the Asterisk CLI to see if you already have the module: pbx*CLI> module show like app_meetme.so Module 0 modules loaded Description Use Count In this case, the module is not present. The most common reason that an Asterisk system does not have the app_meetme module is because DAHDI has not been installed.
phones that all have line keys directly associated with the analog lines. For the purposes of this example, we will say we have two analog lines and four SIP phones. Each SIP phone will have a button for line1 and a button for line2. This section will assume that you have done some configuration up front, including: • Configuring the four SIP phones. For more information on setting up SIP phones, see Chapter 5. • Configuring the two analog lines.
[station3] type = station device = SIP/station3 trunk = line1 trunk = line2 [station4] type = station device = SIP/station4 trunk = line1 trunk = line2 The station configuration is a bit repetitive. Asterisk configuration file template sections come in handy here to collapse the configuration down a bit.
extension (or station2, station3, etc., as appropriate). If the line1 key on the phone is pressed, a call should be sent to the station1_line1 extension (or station2_line1, etc.). Any time that a phone goes off-hook or a line key is pressed, the call that is made will immediately connect it to one of the analog lines. For a line that is not already in use, the analog line will be providing a dialtone, and the user will be able to send digits to make a call.
• Ensure that if the Line 1 key on station1 is pressed a call is sent to the sta tion1_line1 extension, and so on. Key System Example with SIP Trunks This example is intended to be identical in functionality to the previous example. The difference is that instead of using analog lines as trunks, we will use a connection to a SIP provider that will terminate the calls to the PSTN. For more information on setting up Asterisk to connect to a SIP provider, see Chapter 7. sla.conf The sla.
extensions.conf As in the last example, you will need line1 and line2 contexts to process incoming calls on these trunks: [line1] exten => s,1,SLATrunk(line1) ; ; If the provider specifies your phone number when sending you ; a call, you will need another rule in the dialplan to match that. ; exten => _X.,1,Goto(s,1) [line2] exten => s,1,SLATrunk(line2) exten => _X.,1,Goto(s,1) This example requires an sla_stations context, as well. This is for all calls coming from the phones.
complete the call. In this example, we use the DISA() application locally to provide a dialtone and collect digits. Once a complete number has been dialed, the call will proceed to go out to a SIP provider: [line1_outbound] exten => disa,1,DISA(no-password,line1_outbound) ; ; Add extensions for whatever numbers you would like to ; allow to be dialed.
device = SIP/5001_phone2 trunk = 5001 extensions.conf The first part of the dialplan that is required is what will be executed when extension 5001 is dialed on the PBX. Normally, to call a phone you would use the Dial() application. In this case, we’re going to use the SLATrunk() application. This will take care of ringing both phones and keeping them bridged together: exten => 5001,1,SLATrunk(5001) Next, we will need a context that will be used for making outbound calls from this shared extension.
Additional Configuration The /etc/asterisk/sla.conf file has some optional configuration parameters that were not used in any of the examples in this chapter. To give you an idea of what other behavior can be configured, the options are covered here. This file has a [general] section that is reserved for global configuration options.
ringtimeout = 20 A timeout may be specified in seconds for how long this station will ring before the call is considered unanswered. There is no timeout set by default. ringdelay = 5 A ring delay in seconds can be specified for a station. If a delay is specified, this station will not start ringing until this number of seconds after the call first came in on this shared line. There is no delay set by default. hold = private Hold permissions can be specified for a specific station as well.
Conclusion This chapter discussed many aspects of device state handling in Asterisk. We started by discussing the core concepts of device states and extension states, and built up from there. We covered how SIP phones can subscribe to states, tools for creating custom states, and two mechanisms that can be used for distributing states among many servers.
CHAPTER 15 The Automated Attendant I don’t answer the phone. I get the feeling whenever I do that there will be someone on the other end. —Fred Couples In many PBXs it is common to have a menuing system in place to answer incoming calls automatically, and allow the callers to direct themselves to various extensions and resources in the system through menu choices. This is known in the telecom industry as an automated attendant (AA).
In this chapter we talk about building an automated attendant. In Chapter 17 we will discuss IVR.* Designing Your Auto Attendant The most common mistake beginners make when designing an AA is needless complexity. While there can be much joy and sense of accomplishment in the creation of a multilevel AA with dozens of nifty options and oodles of really cool prompts, your callers have a different agenda. The reason people make phone calls is primarily because they want to talk to someone.
a Step or choice Sample prompt address and fax information, please press 3. To repeat these choices press 9, or you can remain on the line or press 0 to be connected to our operator. Notes Filename 1 Please hold while we connect your calls. Transfer to sales queues. holdwhileweconnect.wav 2 Please hold while we connect your call. Transfer to support queue. holdwhileweconnect.wav # n/a Run Directory() application n/a 3 Our address is [address]. Our fax number is [fax number]. etc.
a whole new menu. For example, for a few weeks each year you might want your greeting to say “Season’s greetings” or whatever, but your menu will not need to change. Also, if you want to play a different recording after hours (“Thank you for calling. Our office is now closed.”), you can use different greetings, but the heart of the menu can stay the same.
Selection # It’s good to have the option for the directory as close to the beginning of the recording as possible. Many people will use a directory if they know it is there, but can’t be bothered to listen to the whole menu prompt to find out about it. Impatient people will press 0, so the sooner you tell them about the directory, the more chance you’ll have that they’ll use it, and thus reduce the workload on your receptionist.
Dial by Extension If somebody calls your system and knows the extension she wants to reach, your automated attendant should have code in place to handle this. Although Asterisk can handle an overlap between menu choices and extension numbers (i.e., you can have a menu choice 1 and extensions from 100–199), it is generally best to avoid this overlap.
bit 8-kHz WAV files to be the easiest to work with and, most of the time, the bestpossible quality. There are essentially two ways to get prompts into a system. One is to record sound files in a studio or on a PC, and then move those files into the system. A second way is to record the prompts directly onto the system using a telephone set. We prefer the second method. Our advice is this: don’t get hung up on the complexities of recording audio through a PC or in a studio.§ It is generally not necessary.
Download from Wow! eBook have a maingreeting.wav and a maingreeting.gsm file in your sounds folder, Play back() will select the one that requires the least CPU to play back to the caller). You’ll probably want a separate extension for recording each of the prompts, possibly hidden away from your normal set of extensions, to avoid a mistyped extension from wiping out any of your current menu prompts.
exten => #,1,Verbose(1, same => n,Directory() ; exten => 0,1,Verbose(1, same => n,Dial(SIP/operator) ; Operator extension/queue exten => i,1,Verbose(1, same => n,Playback(invalid) same => n,Goto(s,menuprompt) exten => t,1,Verbose(1, same => n,Goto(0,1) ; ; ; ; You will want to have a pattern match for the various extensions that you'll allow external callers to dial BUT DON'T JUST INCLUDE THE LocalSets CONTEXT OR EXTERNAL CALLERS WILL BE ABLE TO MAKE CALLS OUT OF YOUR SYSTEM ; WHATEVER YOU DO HERE, TEST
IVR We’ll cover Interactive Voice Response (IVR) in more depth in Chapter 17 but before we do that, we’re going to talk about something that is essential to any IVR: database integration is the subject of the next chapter. Conclusion An automated attendant can provide a very useful service to callers. However, if it is not designed and implemented well, it can also be a barrier to your callers that may well drive them away. Take the time to carefully plan out your auto attendant, and keep it simple.
CHAPTER 16 Relational Database Integration Few things are harder to put up with than the annoyance of a good example. —Mark Twain In this chapter we are going to explore integrating some Asterisk features and functions into a database. There are several databases available for Linux, but we have chosen to limit our discussion to the two most popular: PostgreSQL and MySQL.
Installing and Configuring PostgreSQL and MySQL In the following sections we will show how to install and configure PostgreSQL and MySQL on both CentOS and Ubuntu.* It is recommended that you only install one database at a time while working through this section. Pick the database you are most comfortable with, as there is no wrong choice.
Installing MySQL for CentOS To install MySQL on CentOS, run the following command. You will be prompted to install several dependencies. Press Enter to accept, and the MySQL server and dependency packages will be installed: $ sudo yum install mysql-server Install 5 Package(s) Upgrade 0 Package(s) Total download size: 27 M Is this ok [y/N]: y Then start the MySQL database by running: $ sudo service mysqld start Now head to “Configuring MySQL” on page 345 to perform the initial configuration.
Then run the following commands to create the asterisk user in the database and set up permissions: $ createuser -P Enter name of user Enter password for Enter it again: Shall the new role Shall the new user Shall the new user CREATE ROLE to add: asterisk new user: be a superuser? (y/n) n be allowed to create databases? (y/n) y be allowed to create more new users? (y/n) n Now, edit the pg_hba.
Then restart the PostgreSQL server. On CentOS: $ sudo service postgresql restart You need to restart the PostgreSQL service because you made changes to pg_hba.conf, not because you added a new user or changed the password. On Ubuntu: $ sudo /etc/init.d/postgresql-8.4 restart On Ubuntu 10.10 and newer the version number seems to be dropped, so it may just be /etc/init.d/postgresql restart. You can verify your connection to the PostgreSQL server via TCP/IP, like so: $ psql -h 127.0.0.
Then connect to the database console so you can create your asterisk user and set up permissions: $ mysql -u root -p Enter password: After entering the password, you will be presented with the mysql console prompt. You can now create your asterisk user by executing the CREATE USER command. The % is a wildcard indicating the asterisk user can connect from any host and is IDENTIFIED BY the password some_secret_password (which you should obviously change).
On CentOS: $ sudo yum install unixODBC unixODBC-devel libtool-ltdl libtool-ltdl-devel If you’re using a 64-bit installation, remember to add .x86_64 to the end of your development packages to make sure the i386 packages are not also installed, as stability problems can result if Asterisk links against the wrong libraries. On Ubuntu: $ sudo apt-get install unixODBC unixODBC-dev See Chapter 3 for the matrix of packages you should have installed.
Driver Setup FileUsage = /usr/lib/libodbcpsql.so = /usr/lib/libodbcpsqlS.so = 1 On Ubuntu, the /etc/odbcinst.ini file will be blank, so you’ll need to add the data to that configuration file. Add the following to the odbcinst.ini file: [PostgreSQL] Description Driver Setup FileUsage = = = = ODBC for PostgreSQL /usr/lib/odbc/psqlodbca.so /usr/lib/odbc/libodbcpsqlS.
Configuring ODBC for MySQL Configuration for the MySQL ODBC driver is done in the /etc/odbcinst.ini file. On CentOS the default file already contains some data, including that for MySQL, but it needs to be uncommented and requires a couple of changes. Replace the existing text with the following: [MySQL] Description = ODBC for MySQL Driver = /usr/lib/libmyodbc3.so Setup = /usr/lib/libodbcmyS.so FileUsage = 1 On Ubuntu, the /etc/odbcinst.
On Ubuntu 10.10, the socket location is /var/run/mysqld/mysqld.sock. Configuring ODBC for Microsoft SQL Connecting to Microsoft SQL (MS SQL) is similar to connecting to either MySQL or PostgreSQL, as we’ve previously discussed. The configuration of MS SQL is beyond the scope of this book, but the following information will get your Asterisk box configured to connect to your MS SQL database once you’ve enabled the appropriate permissions on your database.
Once you’ve configured the drivers, you need to modify the /etc/odbc.ini file to control how to connect to the database: [asterisk-connector] Description = MS SQL connection to 'asterisk' database Driver = FreeTDS Database = asterisk Server = 192.168.100.1 UserName = asterisk Password = welcome Trace = No TDS_Version = 7.0 Port = 1433 In the next section, you will be able to validate your connection to the MS SQL server.
Almost everything in this chapter is turned on by default. You will want to run make menuselect to verify that the ODBC-related modules are enabled. These include cdr_odbc, cdr_adaptive_odbc, func_odbc, func_realtime, pbx_realtime, res_config_odbc, and res_odbc. For voicemail stored in an ODBC database, be sure to select ODBC_STORAGE from the Voicemail Build Options menu. You can verify that the modules exist in the /usr/lib/asterisk/modules/ directory.
Last connection attempt: 1969-12-31 19:00:00 Pooled: No Connected: Yes Managing Databases While it isn’t within the scope of this book to teach you about how to manage your databases, it is worth at least noting briefly some of the applications you could use to help with database management.
A Gentle Introduction to func_odbc The very first use of func_odbc, which occurred while its author was still writing it, is also a good introduction to its use. A customer of one of the module’s authors noted that some people calling into his switch had figured out a way to make free calls with his system.
of ways in which this might be used, such as for managing users or allowing the sharing of dynamic information within a clustered set of Asterisk machines. What func_odbc allows you to do is define SQL queries to which you assign function names. In effect, you are creating custom functions that obtain their results by executing queries against a database. The func_odbc.conf file is where you specify the relationships between the function names you create and the SQL statements you wish them to perform.
Still, when they do get into the office, they’d like the system to know which desks they are sitting at, so that their calls can be directed there. Also, the boss wants to be able to track when they are in the office and control calling privileges from those phones when no one is there. This need is typically solved by what is called a hot-desking feature, so we have built one for you in order to show you the power of func_odbc. Lets start with the easy stuff, and create two desktop phones in the sip.
pin int4, context text, status bool DEFAULT false, "location" text, CONSTRAINT ast_hotdesk_id_pk PRIMARY KEY (id) ) WITHOUT OIDS; For MySQL: $ mysql -u asterisk -p asterisk Enter password: Then create the table with the following bit of SQL: CREATE TABLE ast_hotdesk ( id serial NOT NULL, extension int8, first_name text, last_name text, cid_name text, cid_number varchar(10), pin int4, context text, status bool DEFAULT false, location text, CONSTRAINT ast_hotdesk_id_pk PRIMARY KEY (id) ); The table informa
At the PostgreSQL console, run the following commands: asterisk=> INSERT INTO ast_hotdesk ('extension', 'first_name', 'last_name',\ 'cid_name','cid_number', 'pin', 'context', 'location') \ VALUES (1101, 'Leif', 'Madsen', 'Leif Madsen', '4165551101', '555',\ 'longdistance','0000FFFF0001'); At the MySQL console, run the following commands: mysql> INSERT INTO ast_hotdesk (extension, first_name, last_name, cid_name, cid_number, pin, context, location) VALUES (1101, 'Leif', 'Madsen', 'Leif Madsen', '4165551101'
We’re not done writing this extension yet, but let’s pause for a moment and see where we’re at so far. When a sales agent sits down at a desk, he logs in by dialing hash (#) plus his own extension number. In this case we have allowed the 1101 through 1105 extensions to log in with our pattern match of _#110[1-5]. You could just as easily make this less restrictive by using _#11XX (allowing 1100 through 1199). This extension uses func_odbc to perform a lookup with the HOTDESK_INFO() dialplan function.
Figure 16-1. Relationships between func_odbc.conf, res_odbc.conf, /etc/odbc.ini (unixODBC), and the database connection This would return the value located in the database within the status column where the extension column equals 1101. The status and 1101 we pass to the HOTDESK_INFO() function are then placed into the SQL statement we assigned to the readsql attribute, available as ${ARG1} and ${ARG2}, respectively. If we had passed a third option, this would have been available as ${ARG3}.
A simple example follows. Suppose we have the following func_odbc.conf: [ALL_AVAIL_EXTENS] prefix=GET dsn=asterisk-connector mode=multirow readsql=SELECT extension FROM ast_hotdesk WHERE status = '${ARG1}' and a dialplan in extensions.
After the SQL statement is executed, the value returned (if any) is assigned to the RETURNED_VALUE channel variable. Using the ARRAY() Function In our example, we are utilizing two separate database calls and assigning those values to a pair of channel variables, ${E}_STATUS and ${E}_PIN.
Remember that in a traditional phone system all extensions must be numbers, but in Asterisk, extensions can have names as well. A possible advantage of using an extension that’s not a number is that it will be much harder for a user to dial it from her phone and, thus, more secure. We’re going to use several named extensions in this example.
; *** This line should have no line breaks readsql=SELECT COUNT(status) FROM ast_hotdesk WHERE status = '1' AND location = '${ARG1}' If there are no other agents logged into the device, we update the login status for this user with the HOTDESK_STATUS() function: ; Continuation of the valid_login extension below same => n,Set(USERS_LOGGED_IN=${HOTDESK_CHECK_PHONE_ LOGINS(${LOCATION})}) same => n,GotoIf($[${USERS_LOGGED_IN} > 0]?logout_login,1) same => n(set_login_status),NoOp() ; Set the status for the phon
loop, but it’s a good example of how you might update or parse multiple rows in the database.§ The first part of our dialplan returns an ID number that we can use with the ODBC_FETCH() function to iterate through the values returned.
variable, which is set by the HOTDESK_STATUS() function. This tells us how many rows were affected in the SQL UPDATE, which we assume to be 1.
[hotdesk_outbound] exten => _X.,1,NoOp() same => n,Set(LOCATION=${CUT(CHANNEL,/,2)}) same => n,Set(LOCATION=${CUT(LOCATION,-,1)}) same => n,Set(WHO=${HOTDESK_PHONE_STATUS(${LOCATION})}) same => n,GotoIf($[${ISNULL(${WHO})}]?no_outgoing,1) same => n,Set(${WHO}_CID_NAME=${HOTDESK_INFO(cid_name,${WHO})}) same => n,Set(${WHO}_CID_NUMBER=${HOTDESK_INFO(cid_number,${WHO})}) same => n,Set(${WHO}_CONTEXT=${HOTDESK_INFO(context,${WHO})}) same => n,Goto(${${WHO}_CONTEXT},${EXTEN},1) [international] exten => _011.
same => n,Playback(silence/2&pls-try-call-later) same => n,Hangup() Our service_provider might look something like this in sip.conf: [service_provider] type=friend host=switch1.service_provider.
from the Asterisk CLI, or reload the module associated with the configuration file (e.g., using module reload chan_sip.so). When using static realtime, we tell Asterisk which files we want to load from the database using the following syntax in the extconfig.conf file: ; /etc/asterisk/extconfig.conf filename.conf => driver,database[,table] If the table name is not specified, Asterisk will use the name of the file as the table name instead.
A Word About Metrics The metrics in static realtime are used to control the order in which objects are read into memory. Think of the cat_metric and var_metric as the original line numbers in the flat file. A higher cat_metric is processed first, because Asterisk matches categories from bottom to top. Within a category, through, a lower var_metric is processed first, because Asterisk processes the options top-down (e.g.
musiconhold.conf => odbc,asterisk,ast_config Then connect to the Asterisk console and perform a reload: *CLI> module reload res_musiconhold.so You can now verify that your music on hold classes are loading from the database by running moh show classes: *CLI> moh show classes Class: general Mode: files Directory: /var/lib/asterisk/moh And there you go: musiconhold.conf loaded from the database. If you have issues with the reload of the module loading the data into memory, try restarting Asterisk.
You may have noticed we used the same table for both the sippeers and sipusers. This is because there will be a type field (just as if we were defining the type in the sip.conf file) that will let us define a type of user, peer, or friend. If you unload chan_sip.so and then load it back into memory (i.e., using module unload chan_sip.so followed by module load chan_sip.so) after configuring extconfig.
Column name Column type secret Varchar 128 context Varchar 128 host Varchar 128 ipaddr Varchar 128 port Varchar 5 regseconds Bigint defaultuser Varchar 128 fullcontact Varchar 128 regserver Varchar 128 useragent Varchar 128 lastms Integer For each peer you want to register, you need to insert data in the columns type, name, secret, context, host, and defaultuser. The rest of the columns will be populated automatically when the peer registers.
Additional options in sip.conf exist for realtime peers. These are defined in the [general] section and described in Table 16-5. Table 16-5. Realtime options in sip.conf Configuration option Description rtcachefriends Caches peers in memory on an as-needed basis after they have contacted the server. That is, on Asterisk start, the peers are not loaded into memory automatically; only after a peer has contacted the server (e.g., via a registration or phone call) is it loaded in memory.
There are many more options for that we can define for SIP friends, such as the caller ID; adding that information is as simple as adding a callerid column to the table. See the sip.conf.sample file for more options that can be defined for SIP friends. Storing Call Detail Records (CDRs) Call detail records (CDRs) contain information about calls that have passed through your Asterisk system. They are discussed further in Chapter 24.
After creating your table in the database (which we’ll assume you’ve called cdr), you need to configure the cdr_adaptive_odbc.conf file in the /etc/asterisk/ folder. The following example will utilize the asterisk connection we’ve defined in res_odbc.conf and store the data in the cdr table: ; cdr_adaptive_odbc.conf [adaptive_connection] connection=asterisk table=cdr Yes, really, that’s all you need. After configuring cdr_adaptive_odbc.conf, just reload the cdr_adaptive_odbc.
After the alteration to your database and dialplan, you can place a call and then look at your CDRs. You should see something like the following: +--------------+----------+---------+------------+ | src | duration | billsec | route_rate | +--------------+----------+---------+------------+ | 0000FFFF0008 | 37 | 30 | 0.
In some situations you may specify a connection where you only want to log calls from a specific source, or to a specific destination.
Download from Wow! eBook This section builds upon previous configuration sections in this chapter. If you have not already done so, be sure to follow the steps in the sections “Installing PostgreSQL for CentOS” on page 342 and “Installing and Configuring ODBC” on page 346 before continuing. In the latter section, be sure you have enabled ODBC_STORAGE in the menuselect system under Voicemail Options.
We’ll be making use of the PostgreSQL procedural language called pgSQL/PL to create a function. This function will be called from a trigger that gets executed whenever we modify or delete a record in the table used to store voicemail messages. This is so the data is cleaned up and not left as an orphan in the database: CREATE FUNCTION vm_lo_cleanup() RETURNS "trigger" AS $$ declare msgcount INTEGER; begin -- raise notice 'Starting lo_cleanup function for large object with oid %',old.
context varchar(80), macrocontext varchar(80), callerid varchar(40), origtime varchar(40), duration varchar(20), mailboxuser varchar(80), mailboxcontext varchar(80), recording lo, label varchar(30), "read" bool DEFAULT false, flag varchar(10) ); And now we need to associate a trigger with our newly created table in order to perform cleanup whenever we change or delete a record in the voicemessages table: CREATE TRIGGER vm_cleanup AFTER DELETE OR UPDATE ON voicemessages FOR EACH ROW EXECUTE PROCEDURE vm_lo_
Configuring voicemail.conf for ODBC Storage There isn’t much to add to the voicemail.conf file to enable the ODBC voicemail storage. In fact, it’s only three lines! Normally, you probably have multiple format types defined in the [general] section of voicemail.conf, but we need to set this to a single format because we can only save one file (format) to the database. The wav49 format is a compressed WAV file format that should be playable on both Linux and Microsoft Windows desktops.
Then verify that your new mailbox loaded successfully: *CLI> voicemail show users for default Context Mbox User default 1000 J.P. Wiser Zone NewMsg 0 Testing ODBC Voicemail Let’s create some simple dialplan logic to leave and retrieve some voicemail from our test voicemail box.
Then configure your phone or client with the username odbc_test_user and password , and place a call to extension 100 to leave a voicemail.
Verifying binary data stored in PostgreSQL To make sure the recording really did make it into the database, use the psql application: $ psql -h localhost -U asterisk asterisk Password: then run a SELECT statement to verify that you have some data in the voicemessages table: localhost=# SELECT uniqueid,dir,callerid,mailboxcontext,recording FROM voicemessages; uniqueid | dir | callerid ---------+--------------------------------------------------+-------------1 | /var/spool/asterisk/voicemail/default/1000/INB
Verifying binary data stored in MySQL To verify that your data is being written correctly, you can use the mysql application to log into your database and export the voicemail recording to a file: $ mysql -u asterisk -p asterisk Enter password: Once logged into the database, you can use a SELECT statement to dump the contents of the recording to a file.
might if you are going to use it for overhead paging), or copy the file to another system and listen to it there: $ play /tmp/voicemail_recording.wav voicemail_recording.wav: File Size: Encoding: Channels: Samplerate: Replaygain: Duration: In:100% Done. 7.28k Bit Rate: 13.1k GSM 1 @ 16-bit 8000Hz off 00:00:04.44 00:00:04.44 [00:00:00.00] Out:35.5k [ | ] Hd:4.4 Clip:0 Conclusion In this chapter, we learned about several areas where Asterisk can integrate with a relational database.
CHAPTER 17 Interactive Voice Response One day Alice came to a fork in the road and saw a Cheshire cat in a tree. “Which road do I take?” she asked. “Where do you want to go?” was his response. “I don’t know,” Alice answered. “Then,” said the cat, “it doesn’t matter.” —Lewis Carroll In this chapter we will talk about IVR. If what you want is an automated attendant, we have written a chapter for that as well (Chapter 15).
Components of an IVR The most basic elements of an IVR are quite similar to those of an automated attendant, though the goal is different. We need at least one prompt to tell the caller what the IVR expects from him, a method of receiving input from the caller, logic to verify that the caller’s response is valid input, logic to determine what the next step of the IVR should be, and finally, a storage mechanism for the responses, if applicable.
Argument Purpose attempts The number of times to play the prompt. If the caller fails to enter anything, the Read() application can automatically re-prompt the user. The default is one attempt. timeout The number of seconds the caller has to enter his input. The default value in Asterisk is 10 seconds, although it can be altered for a single prompt using this option, or for the entire session by assigning a value using the dialplan function TIMEOUT(response).
IVR Design Considerations When designing your own IVR, there are some important things to keep in mind. We’ve put together this list of some things to do, and things not to do in your IVR. Do • Keep it simple. • Have an option to dial 0 to reach a live person. • Handle errors gracefully. Don’t • • • • Think that an IVR can completely replace people. Use your IVR to show people how clever you are. Try to replicate your website with an IVR. Bother building an IVR if you can’t take numeric input.
programmer but are very adept with Asterisk dialplans and databases, you’ll love func_odbc just as much as we do. Check it out in Chapter 16. AGI The Asterisk Gateway Interface is such an important part of integrating external applications with Asterisk that we gave it its own chapter. You can find more information in Chapter 21.
On Ubuntu: $ sudo apt-get install libcurl4-openssl-dev The Dialplan The dialplan for our example IVR is very simple. The CURL() function will retrieve our IP address from http://www.whatismyip.org, and then SayAlpha() will speak the results to the caller: exten => same same same same *764,1,Verbose(2, Run CURL to get IP address from whatismyip.org) => n,Answer() => n,Set(MyIPAddressIs=${CURL(http://www.whatismyip.
same => n,Background(${which}) same => n,Goto(s,step2) exten => 2,1,Set(step2count=0) same => n,Playback(prompt-waitforbeep) same => n,Record(${CHANNEL(uniqueid)}.wav) same same same same same same same => => => => => => => n(listen),Playback(${CHANNEL(uniqueid)}) n,Set(step3count=0) n,Read(saveornot,prompt-1tolisten-2tosave-3todiscard,1) n,GotoIf($["${saveornot}" = "1"]?listen) n,GotoIf($["${saveornot}" = "2"]?saveit) n,System(rm -f /var/lib/asterisk/sounds/${CHANNEL(uniqueid)}.
While on the surface, the idea of a speaking computer is very attractive, the reality is that it has limited usefulness. More information about integration of text-to-speech with Asterisk can be found in Chapter 18. Speech Recognition As soon as we’ve convinced computers to talk to us, we will naturally want to be able to talk to them.
CHAPTER 18 External Services Correct me if I’m wrong—the gizmo is connected to the flingflang connected to the watzis, watzis connected to the doo-dad connected to the ding dong. —Patrick B. Oliphant Asterisk is pretty nifty all by itself, but one of the most powerful, industry-changing, revolutionary aspects of Asterisk is the sheer number of wonderful ways it may be connected to external applications and services. This is truly unprecedented in the world of telecom.
Calendar Integration Asterisk can be integrated with several different kinds of calendar formats, such as iCal, CalDAV, MS Exchange (Exchange 2003), and MS Exchange Web Services (Exchange 2007 and later). Integrating Asterisk with your calendar gives you the ability to manipulate call routing based on your current calendar information. For example, if you’re not going to be in your office for the afternoon it may make sense for people ringing your desk phone to be routed directly to your voicemail.
If you are planning on compiling the res_calendar_ews module, you will need to have a version of neon greater than or equal to 0.29. Currently CentOS is shipping with 0.25, so you will have to compile the neon library and link to it from the configure script. This can be done via ./ configure --with-neon29=. The next step is to install the libical-devel dependency.
up and running far quicker. Of course, once you’re comfortable with configuring calendaring support in Asterisk, you can connect it to any calendaring server you desire. The first step is to make sure you have a Gmail (http://www.gmail.com) account with Google, which will get you access to a calendaring server. Once you’ve logged into your Gmail account, there should be a link to your calendar in the upper-left corner. Click on the Calendar link and insert a couple of items for the next hour or two.
$ asterisk -r *CLI> module load res_calendar.
If you have not configured any of the Notify options but have an alarm set to remind you in the calendar, you may get a WARNING message such as: WARNING[5196]: res_calendar.c:648 do_notify: Channel should be in form Tech/Dest (was '') The reason for the warning is that an alarm was set for notification about the start of the meeting, but Asterisk was unable to generate a call due to values not being configured to place the call.
When the event rolls around, Asterisk will generate a call to you and play back the sound file this-is-yr-wakeup-call.
When the event time arrives, our device will receive a call, and when that call is answered another call will be placed to the endpoint with which we wish to have our meeting.
; *** This line should not have any line breaks same => n,Read(CheckMeetingAcceptance,to-confirm-wakeup&press-1&otherwise &press-2,,1) same => n,GotoIf($["${CheckMeetingAcceptance}" != "1"]?hangup,1) same => n,Playback(silence/1&pls-rcrd-name-at-tone&and-prs-pound-whn-finished) ; ; ; ; ; ; ; We set a random number and assign it to the end of the recording so that we have a unique filename in case this is used by multiple people at the same time.
been dialed and answered (or perhaps not answered), the organizer will be placed into the call, at which point the meeting will start. This type of functionality increases the likelihood that the meeting will start on time, and it means the meeting organizer doesn’t have to continually perform roll call as new participants continue to join after the call is supposed to start (which invariably happens, with people’s schedules typically being fairly busy).
; same => n,MeetMe(${CalLocation},dA) same => n(hangup),Hangup() [MeetingOriginator] exten => _[A-Za-z0-9].,1,NoOp() same => n,Set(Peer=${FILTER(A-Za-z0-9,${EXTEN})}) ; Originate calls to a peer as passed to us from the Local channel. Upon ; answer, the called party should execute the dialplan located at the ; _meetme-XXXX extension, where XXXX is the conference room number.
same => n(unavail),VoiceMail(${CurrentExten}@shifteight,u) same => n,Hangup() And here is a slightly more elaborate section of dialplan that utilizes a few of the tools we’ve learned throughout the book, including DB_EXISTS(), GotoIf(), and the IF() function: exten => _3XXX,1,Verbose(2,Simple calendar busy check example) same => n,Set(CurrentExten=${EXTEN}) same => n,GotoIf($[${DB_EXISTS(extension/${CurrentExten}/device)}]?:no_device,1) same => n,Set(CurrentDevice=${DB_RESULT}) same => n,GotoIf($[${DB_EXIS
On the left side of the Google calendar interface will be a link labeled Add. Clicking on this will open a new window where you can create the calendar. Go ahead and do that now. We’ve called ours “Phone Calls.” Now we need to enable CalDAV calendar syncing for our calendar. Information about how to do this is located at http://www.google.com/support/mobile/bin/answer.py?an swer=151674.
Now that we have our calendar configured, we need to load it into memory, which can be done by reloading the res_calendar.so module: *CLI> module reload res_calendar.
Many possibilities exist for the CALENDAR_WRITE() function; this is just one that we’ve implemented and enjoy. Conclusion In this section we’ve learned how to integrate Asterisk with an external calendar server such as that provided by Google, but the concepts for attaching to other calendaring servers remain the same. We explored how to set up a meeting between two participants, and how to set up a multiparty conference using information obtained from the description field in the calendar.
ability to listen to, forward, and mark voicemail messages with the same flexibility that the Asterisk VoiceMail() dialplan application gives. Asterisk will be aware of the statuses of those messages when the users next log in via the phone system. As the number of administrators integrating Asterisk with their IMAP servers has increased, the number of bugs filed and fixed has first increased and then decreased, to the point where IMAP integration can be considered stable enough for production use.
Compiling the IMAP library Now that we have our dependencies satisfied, we can compile the IMAP library that Asterisk will use to connect to our IMAP server. The first thing to do is change to the thirdparty directory located under the asteriskcomplete directory. If you have not already created this directory, do so now: $ cd ~/src/asterisk-complete $ mkdir thirdparty $ cd thirdparty Next up is downloading the IMAP toolkit and compiling it.
To compile for a 32-bit platform with OpenSSL support and a preference for connecting via IPv4: $ make lnp EXTRACFLAGS="-I/usr/include/openssl" IP6=4 If you don’t wish to compile with OpenSSL support, simply remove the -I/usr/ include/openssl from the EXTRACFLAGS option. If you would prefer connecting by IPv6 by default, simply don’t specify the IP6=4 option. When installing IMAP support, we have always compiled the c-client library from source.
web-based IMAP server such as that supplied by Google’s Gmail.‖ Our instructions are going to show how to connect Asterisk to a Gmail account with IMAP enabled, as it requires the least amount of effort to get up and running with IMAP voicemail, but these instructions can easily be adapted for use with any existing IMAP server. Enabling IMAP on your Gmail account. Enabling IMAP support on your Gmail account is straightforward (see Figure 18-1).
We’re going to demonstrate how to connect to an IMAP-enabled Gmail account and use that to store and retrieve our voicemail messages. If you haven’t already, read the section “Enabling IMAP on your Gmail account” before proceeding. The final step is configuring voicemail.conf to connect to the server. In voicemail.conf, add the following lines to the [general] section.
Table 18-2 shows some of the other options available to us. Table 18-2. Additional IMAP voicemail options a Option Description imapfolder Provides the name of the folder in which to store voicemail messages on your IMAP server. By default they are stored in the INBOX.a imapgreetings Defines whether voicemail greetings are stored on the IMAP server or stored locally on the server. Valid values are yes or no. imapparentfolder Defines the parent folder on the IMAP server.
We’ve removed the email address from the third field because we’re not going to use sendmail to email us voicemails anymore: they are just going to be stored on the email server directly now. We’ve configured the mailbox to connect with the IMAP username of leif@shifteight.org (because we’ve enabled Google Apps for the domain that hosts our email) and are connecting using the IMAP password secret. After configuring Asterisk, we need to reload the app_voicemail.so module.
Compiling Jabber Support into Asterisk The res_jabber module contains various dialplan applications and functions that are useful from the Asterisk dialplan. It is also a dependency of the chan_gtalk and chan_jingle channel modules. To get started with XMPP integration in Asterisk, we need to compile res_jabber. CentOS dependencies To install res_jabber, we need the iksemel development library (http://code.google.com/ p/iksemel/).
You must already have a Gmail account, which you can get at http:// www.gmail.com. Our jabber.conf file should look like this: [general] debug=no autoprune=no autoregister=yes auth_policy=accept [asterisk] type=client serverhost=talk.google.com username=asterisk@shifteight.org secret= port=5222 usetls=yes usesasl=yes status=available statusmessage="Ohai from Asterisk" Let’s take a quick look at some of the options we just set so you understand what is going on.
Option Description status Defines our default connection status when signed into our account. Available options are: chat, available, away, xaway, and dnd. statusmessage Sets a custom status message to use when connected with Asterisk, such as "Connected Via Asterisk". Use double quotes around the message. buddy Used to manually add buddies to the list upon connection to the server. You can specify multiple buddies on multiple buddy lines (e.g., buddy=jim@shifteight.org).
Here is a simple example to get us started: [LocalSets] exten => 104,1,Answer() ; *** This line should not have any line breaks same => n,JabberSend(asterisk,jim@shifteight.org,Incoming call from ${CALLERID(all)}) same => n,Dial(SIP/0000FFFF0002,30) same => n,Hangup() This example demonstrates how to use the JabberSend() application to send a message to someone prior to dialing a device. Let’s break down the values we’ve used. The first argument, asterisk, is the section header we defined in the jabber.
same => n,JabberSend(asterisk,leif.madsen@gmail.com,Incoming call from ${CALLERID(all)}. Press 1 to route to desk. Press 2 to send to voicemail.) same same same same => => => => n,Set(JabberResponse=${JABBER_RECEIVE(asterisk,leif@shifteight.
Download from Wow! eBook much time to respond. However, if we set the response long enough to make it comfortable for the user to send a response, we cause unnecessary delay in calling a device or sending to voicemail. We can skirt around this issue by using a Local channel. This allows us to execute two sections of dialplan simultaneously, sending a call to the device at the same time we’re waiting for a response from JABBER_RECEIVE().
With the examples provided here serving as a springboard, you should be able to develop rich applications that make use of sending and receiving messages via XMPP servers.
channel drivers in Asterisk. For now chan_gtalk is fairly simple, but future versions of Asterisk may add this feature. Our gtalk.conf file looks like this: [general] bindaddr=0.0.0.0 allowguests=yes ; Address to bind to ; Allow calls from people not in contact list ; Optional arguments ; externip= ; stunaddr=
specify which account calls will be coming from with the connection option, which we’ve set to the account created in jabber.conf. The chan_gtalk module does not support reloading the configuration. If you change the configuration, you will have to either restart Asterisk or unload and reload the module, which can only be done when no GTalk calls are up. You can do that using the following commands: *CLI> module unload chan_gtalk.so *CLI> module load chan_gtalk.
send the DTMF prior to ringing your device by adding the two boldface lines shown here prior to performing the Dial(): [gtalk_incoming] exten => s,1,Verbose(2,Incoming call from ${CALLERID(all)}) same => n,Answer() same => n,Wait(2) same => n,SendDTMF(2) same => n,Dial(SIP/0000FFFF0001,30) same => n,Hangup() Here, we’re using the Wait() and SendDTMF() applications to first wait 2 seconds after answering the call (which is the time when the call screening message will start) and then accept the call automat
Skype Integration Skype integration now exists with Asterisk through a commercial module from Digium called Skype for Asterisk (SFA).‡ The SFA module loads directly into Asterisk and allows communication with all users on the Skype network directly by using an account created on the Skype Manager.
Users configured in chan_skype.conf must be created with the Skype Manager interface. Personal Skype IDs are not allowed. Our example Skype user will be pbx.shifteight.org. We’ll configure this user in chan_skype.conf. There are additional options that could be set here, but for our purposes we’re keeping it simple: [general] default_user=pbx.shifteight.org [pbx.shifteight.
Our dialplan simply answers the call and attempts to place a call to vuc.me,§ wait 30 seconds for that user to answer, and, if there is no answer, play back a message saying that the user is currently unavailable before hanging up. We could, of course, be more elaborate with our dialplan; for example, we could turn this into a Macro() or GoSub() routine so we just needed to pass in the name of the person we wish to call.
for 30 seconds, and then (if there is no answer or the device is busy or unavailable) play back a prompt that says the user is currently unavailable, followed by a hangup. We’ve just shown you how to place and receive calls via Skype. The following sections will show you how to send and receive messages via the Skype network, and how to place calls to your Skype buddies without assigning extension numbers to them.
the SkypeChatSend() and SKYPE_CHAT_RECEIVE() dialplan application and function, respectively: exten => 106,1,Answer() ; All text must be on a single line. same => n,SkypeChatSend(pbx.shifteight.org,tfot.madsen,Incoming call from ${CALLERID(all)}. Press 1 to route to desk. Press 2 to send to voicemail.) ; Wait for a response for 6 seconds. ; *** This line should not have any line breaks same => n,Set(SkypeResponse= ${SKYPE_CHAT_RECEIVE(pbx.shifteight.org,tfot.
involved for text-to-speech to really make a lot of sense—otherwise, why not use prerecorded prompts instead? However, an idea finally came to us, based on the fact that having to assign extension numbers to each Skype user we wanted to call was not only cumbersome, but was a mental exercise we weren’t willing to take on.
Configuring OpenLDAP While a discussion of the installation and configuration of an LDAP server is beyond the scope of this chapter, it is certainly applicable to show you how we expanded our initial LDAP schema to include the information required for Asterisk integration. Our initial installation followed instructions from the Ubuntu documentation page located at https://help.ubuntu.com/10.04/serverguide/C/openldap-server.html. We only needed to follow the instructions up to and including the backend.
We’ll insert the returned value (without the hyphen) into the following file within the userPassword field, prefixed with {md5}: $ cat > astuser.
With the file created, we can add the user to our LDAP server: $ sudo ldapadd -x -D cn=admin,dc=shifteight,dc=org -f astusers.ldif -W Enter LDAP Password: adding new entry "uid=rbryant,ou=people,dc=shifteight,dc=org" Our user has now been imported into LDAP. The next step is to configure Asterisk to connect to the LDAP server and allow users to authenticate and register their phones.
configure how Asterisk is going to connect to our LDAP server. Our first option is url, which will determine how to connect to the server. We have defined a connection as ldap://172.16.0.103:389, which will connect to the LDAP server at IP address 172.16.0.103 on port 389. If you have a secure connection to your LDAP server, you can replace ldap:// with ldaps://. Additionally, we have set protocol=3 to state that we’re connecting with protocol version 3, which in most (if not all) cases will be correct.
Configuring extconfig.conf Our next step is to tell Asterisk what information to load via realtime and what technology to use. Using the extconfig.conf file, we have the option of loading several modules dynamically (and we can also load files statically). For more information about Asterisk realtime, see “Using Realtime” on page 368. For our example, we’re going to configure the sipusers and sippeers dynamic realtime objects to load our SIP peers from LDAP.
To enable peer caching in Asterisk, use the rtcachefriends option in sip.conf: rtcachefriends=yes There are additional realtime options as well, such as rtsavesysname, rtupdate, rtauto clear, and ignoreregexpire. These are all explained in the sip.conf.sample file located within your Asterisk source. Text-to-Speech Utilities Text-to-speech utilities are used to convert strings of words into audio that can be played to your callers.
This function name may be added to the server safe functions." (let ((wholeutt (utt.synth (eval (list 'Utterance 'Text string))))) (utt.wave.resample wholeutt 8000) (utt.wave.rescale wholeutt 5) (utt.send.wave.client wholeutt))) After adding that, you need to start the Festival server: $ sudo festival_server 2>&1 > /dev/null & Using menuselect from your Asterisk source directory, verify that the app_festival application has been selected under the Applications heading.
Alternatively, if you’re having issues with the Festival server, you could use the following method to generate files with the text2wave application supplied with the festival package: exten => 202,1,Verbose(2,Trying out Festival) same => n,Answer() ; *** This line should not have any line breaks same => n,System(echo "This is a test of Festival" | /usr/bin/text2wave -scale 1.5 -F 8000 -o /tmp/festival.wav) same => n,Playback(/tmp/festival) same => n,System(rm -f /tmp/festival.
CHAPTER 19 Fax Have no fear of perfection. You’ll never reach it. —Salvador Dali The concept of facsimile transmission has been around for over 100 years, but it was not until the 1980s that the use of fax machines became essential in business. This lasted for perhaps two decades. Then the Internet came along, and very shortly after that, the fax quickly became almost irrelevant. What Is a Fax? A fax machine allows a facsimile (copy) of a document to be transmitted across a telephone line.
Asterisk Fax cannot: • Print faxes • Accept documents for transmission in any format other than TIFF Receiving is relatively simple, since the format of the document is determined at the sending end, and thus all Asterisk needs to do is store the document. Transmitting is somewhat more complex, since the transmitting end is responsible for ensuring that the document to be sent is in the correct format for faxing.
This will install the library in the /usr/local/lib/ folder. On many Linux systems this folder is not automatically part of the library path (libpath), so it will need to be added manually. Adding the spandsp Library to Your libpath In order to make the spandsp library visible to all applications on the system, the folder where it is located must be added to the libpath for the system. This is typically done by editing files in the /etc/ld.so.conf.d/ directory.
At this point the SendFAX() and ReceiveFAX() dialplan applications will be available to you. Disabling spandsp (Should You Want to Test Digium Fax) The spandsp library and the Digium fax library, discussed in the next section, are mutually exclusive. If you want to try out the Digium fax product, you will need to ensure that spandsp does not load. To disable spandsp in Asterisk, simply edit your /etc/asterisk/modules.conf file as follows: noload => res_fax_spandsp.so Save the changes and restart Asterisk.
Incoming Fax Handling Received faxes are commonly encoded in Tagged Image File Format (TIFF). This graphics file format, while not as well known as JPEG or GIF, is not as obscure as one might think. In fact, we suspect your computer (whether you’re running Windows, Linux, or MacOS) will already have the ability to interpret TIFF files built in. While it has become popular to offer PDF as a delivery format for received faxes, we’re not sure this is strictly required, since TIFF is so ubiquitous.
software would have a difficult time making sense of). In other words, unless you dedicate a DID to each user who might receive a fax, Asterisk isn’t going to be able to do much more than send all faxes to a single email address. You could code something in the dialplan to handle this, though, or have an external cron job or other daemon handle distributing the received faxes.
Table 19-1. Possible values for the faxdetect option in chan_dahdi.conf Value Description incoming Enables fax detection on inbound calls. When a fax is detected, applies the faxbuffers option if it has been set and redirects the call to the fax extension in the dialplan. For more information on the faxbuffers option, see “Using Fax Buffers in chan_dahdi.conf” on page 454. outgoing Enables fax detection on outbound calls. The dialplan is not executing on an outbound channel.
Transmitting a Fax from Asterisk To transmit a fax from Asterisk, you must have a TIFF file. How you generate this TIFF is important, and may involve many steps. However, from Asterisk’s perspective the sending of a fax is fairly straightforward.
$ sudo yum -y install ghostscript and in Ubuntu with: $ sudo apt-get install ghostscript Once installed, ghostscript can convert the PDF into an Asterisk-compatible TIFF file with the following command: $ gs -q -dNOPAUSE -dBATCH -sDEVICE=tiffg4 -sPAPERSIZE=letter -sOutputFile= Replace with the name of the output file, and specify the location of your source PDF with .
import import import import import import sys os email base64 shutil socket AMI_HOST AMI_PORT AMI_USER AMI_PASS = = = = "localhost" 5038 "hello" "world" # This script will pull a TIFF out of an email and save it off to disk to allow # the SendFax() application in Asterisk to send it. This is the location on # disk where the TIFF will be stored. TIFF_LOCATION = "/tmp/loremipsum.tif" # Read an email from stdin and parse it. msg = email.message_from_file(sys.
\r Action: Originate\r Channel: Local/s@sendfax/n\r Context: receivefax\r Extension: s\r Priority: 1\r SetVar: SUBJECT=%s\r \r Action: Logoff\r \r """ % (AMI_USER, AMI_PASS, msg['subject']) print ami_commands def my_send(s, data): """Ensure that we send out the whole data buffer. """ sent = 0 while sent < len(data): res = s.send(data[sent:]) if res == 0: break sent = sent + res def my_recv(s): """Read input until there is nothing else to read. """ while True: res = s.
Fax Pass-Through In theory, it should be possible to connect a traditional fax machine to an FXS port of some sort and then pass incoming faxes to that device (see Figure 19-1). This concept is attractive for a few reasons: 1. It allows you to integrate existing fax machines with your Asterisk system. 2. It requires far less configuration in the dialplan. Unfortunately, fax pass-through is not the home run we would like it to be.
This would be placed in your /etc/asterisk/chan_dahdi.conf file and would cause chan_dahdi to create a 96 ms buffer for fax calls and delay start of transmission until the buffer was half full. You would also need to set faxdetect, since the fax buffers are part of the faxdetect functionality: faxdetect = both We have not extensively tested this capability yet, but anecdotal evidence suggests that this should greatly improve the performance of fax pass-through in Asterisk.
CHAPTER 20 Asterisk Manager Interface (AMI) John Malkovich: I have seen a world that NO man should see! Craig Schwartz: Really? Because for most people it’s a rather enjoyable experience. —Being John Malkovich The Asterisk Manager Interface (AMI) is a system monitoring and management interface provided by Asterisk. It allows live monitoring of events that occur in the system, as well enabling you to request that Asterisk perform some action.
This sample configuration is set up to only allow local connections to the AMI. If you intend on making this interface available over a network, it is strongly recommended that you only do so using TLS. The use of TLS is discussed in more detail later in this chapter. Once the AMI configuration is ready, enable the built-in HTTP server by putting the following contents in /etc/asterisk/http.conf: ; ; Enable the built-in HTTP server, and only listen for connections on localhost.
Once you have this working, you have verified that AMI is accepting connections via a TCP connection. AMI over HTTP It is also possible to use the AMI over HTTP. In this section we will perform the same actions as before, but over HTTP instead of the native TCP interface to the AMI. The responses will be delivered over HTTP in the same format as the previous example, since the rawman encoding type is being used. AMI-over-HTTP responses can be encoded in other formats, such as XML.
$ wget "http://localhost:8088/rawman?action=logoff" --load-cookies cookies.txt -O --2010-08-31 12:34:23-Resolving localhost... 127.0.0.1 Connecting to localhost|127.0.0.1|:8088... connected. HTTP request sent, awaiting response... 200 OK Length: 56 [text/plain] Saving to: `STDOUT' Response: Goodbye Message: Thanks for all the fish. 2010-08-31 12:34:23 (696 KB/s) - written to stdout [56/56] The HTTP interface to AMI lets you integrate Asterisk call control into a web service.
a b Option Value/Example Description tlsbindaddr 0.0.0.0 Sets the address to listen on for TLS-based AMI connections. The default is to listen on all addresses (0.0.0.0). tlscertfile /var/lib/asterisk/keys/asterisk.pem Sets the path to the server certificate for TLS. This is required if tlsenable is set to yes. tlsprivatekey /var/lib/asterisk/keys/private.pem Sets the path to the private key for TLS.
The manager.conf configuration file also contains the configuration of AMI user accounts. An account is created by adding a section with the username inside square brackets. Within each [username] section there are options that can be set that will apply only to that account. Table 20-2 lists the options available in a [username] section. Table 20-2. Options for [username] sections a Option Value/Example Description secret password Sets the password used for authentication. This must be set.
Download from Wow! eBook Table 20-3. Available values for AMI user account read/write options Permission identifier read write all Shorthand way of specifying that this user should have access to all available privilege options. Grants user all privilege options. system Allows user to receive general system information, such as notifications of configuration reloads. Allows user to perform system management commands such as Restart, Reload, or Shutdown.
a b c d Permission identifier read write aoc Lets user see Advice of Charge events generated as AOC events are received. Allows user to execute the AOCMessage manager action, for sending out AOC messages. This level has been defined, but it is not currently used anywhere in Asterisk. This level has been defined, but it is not currently used anywhere in Asterisk. The UserEvent action is a useful mechanism for having messages delivered to other AMI clients.
a Option Value/Example Description tlscipher Specifies a list of ciphers for OpenSSL to use. Setting this is optional. To see a list of available ciphers, run openssl ciphers -v at the command line. The OpenSSL development package must be installed for Asterisk to be able to use encryption. On Ubuntu, the package is libssl-dev. On CentOS, the package is openssl-devel.
Figure 20-2. Manager actions Figure 20-3. Manager actions that return a list of data Message Encoding All AMI messages, including manager events, manager actions, and manager action responses, are encoded in the same way. The messages are text-based, with lines terminated by a carriage return and a line-feed character.
Events Manager events always have an Event header and a Privilege header. The Event header gives the name of the event, while the Privilege header lists the privilege levels associated with the event. Any other headers included with the event are specific to the event type. Here’s an example: Event: Hangup Privilege: call,all Channel: SIP/0004F2060EB4-00000000 Uniqueid: 1283174108.
This is the method that was used in the quick-start example, as seen in “AMI over HTTP” on page 459. The second authentication option is HTTP digest authentication.* The next three sections discuss each of the AMI over HTTP encoding options. To indicate that HTTP digest authentication should be used, prefix the encoding type with an a. Once successfully authenticated, Asterisk will provide a cookie that identifies the authenticated session.
/manager encoding The manager encoding type provides a response in simple HTML form. This interface is primarily useful for experimenting with the AMI. Here is an example Login using this encoding type: $ curl -v "http://localhost:8088/manager?action=login&username=hello&secret=world" * About to connect() to localhost port 8088 (#0) * Trying 127.0.0.1... connected * Connected to localhost (127.0.0.1) port 8088 (#0) > GET /manager?action=login&username=hello&secret=world HTTP/1.1 > User-Agent: curl/7.19.
/mxml encoding The mxml encoding type provides responses to manager actions encoded in XML. Here is an example Login using the mxml encoding type: $ curl -v "http://localhost:8088/mxml?action=login&username=hello&secret=world" * About to connect() to localhost port 8088 (#0) * Trying 127.0.0.1... connected * Connected to localhost (127.0.0.1) port 8088 (#0) > GET /mxml?action=login&username=hello&secret=world HTTP/1.1 > User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.
$ wget --load-cookies cookies.txt "http://localhost:8088/mxml?action=waitevent" -O agi set debug on AGI Debugging Enabled -- Executing [500@phones:1] AGI("SIP/0004F2060EB4-00000009", "hello-world.sh") in new stack -- Launched AGI Script /var/lib/asterisk/agi-bin/hello-world.sh AGI Tx >> agi_request: hello-world.
AGI Variants There are a few variants of AGI that differ primarily in the method used to communicate with Asterisk. It is good to be aware of all of the options so you can make the best choice based on the needs of your application. Process-Based AGI Process-based AGI is the simplest variant of AGI. The “quick-start” example at the beginning of this chapter was an example of a process-based AGI script. The AGI script is invoked by using the AGI() application from the Asterisk dialplan.
Pros of Enhanced AGI It has the simplicity of process-based AGI, with the addition of a simple read-only stream of the channel’s audio. This is the only variant that offers this feature. Cons of Enhanced AGI Since a new process must be spawned to run your application for every call, it has the same efficiency concerns as regular process-based AGI. For an alternative way of getting access to the audio outside of Asterisk, consider using JACK. Asterisk has a module for JACK integration, called app_jack.
The default port number for a FastAGI connection is 4573. A different port number can be appended to the URL after a colon. For example: exten => 1234,1,AGI(agi://127.0.0.1:4574) Just as with process-based AGI, arguments can be passed to a FastAGI application. To do so, add them as additional arguments to the AGI() application, delimited by commas: exten => 1234,1,AGI(agi://192.168.1.199,arg1,arg2,arg3) FastAGI also supports the usage of SRV records if you provide a URL in the form of hagi://.
Additional information on how to use async AGI over the AMI can be found in the next section. Pros of async AGI An existing AMI application can be used to control calls using AGI commands. Cons of async AGI It is the most complex method of using AGI to implement. Setting Up /etc/asterisk/manager.conf for Async AGI “Configuration” on page 460 discusses the configuration options in manager.conf in detail. To make use of async AGI, an AMI account must have the agi permission for both read and write.
Table 21-1. AGI environment variables Variable Value / Example Description agi_request hello-world.sh The first argument that was passed to the AGI() or EAGI() application. For process-based AGI, this is the name of the AGI application that has been executed. For FastAGI, this would be the URL that was used to reach the FastAGI server. agi_channel SIP/ 0004F2060EB4-00000009 The name of the channel that has executed the AGI() or EAGI() application. agi_language en The language set on agi_channel.
For an example of the variables that might be sent to an AGI application, see the AGI communication debug output in “Quick Start” on page 475. The end of the list of variables will be indicated by a blank line. Example 21-1 handles these variables by reading lines of input in a loop until a blank line is received. At that point, the application continues and begins executing AGI commands. Async AGI When you use async AGI, Asterisk will send out a manager event to initiate the async AGI session.
A full list of available AGI commands can be retrieved from the Asterisk console by running the command agi show commands. These commands are described in Table 21-2. To get more detailed information on a specific AGI command, including syntax information for any arguments that a command expects, use agi show commands topic . For example, to see the built-in documentation for the ANSWER AGI command, you would use agi show commands topic ANSWER. Table 21-2.
AGI command Description SAY DIGITS Say a string of digits. For example, 100 would be said as “one zero zero” if the channel’s language is set to English. SAY NUMBER Say a number. For example, 100 would be said as “one hundred” if the channel’s language is set to English. SAY PHONETIC Say a string of characters, but use a common word for each letter (Alpha, Bravo, Charlie…). SAY DATE Say a given date. SAY TIME Say a given time. SAY DATETIME Say a given date and time using a specified format.
a b AGI command Description SPEECH DEACTIVATE GRAMMAR Deactivate a grammar. SPEECH RECOGNIZE Play a prompt and perform speech recognition, as well as wait for digits to be pressed. GOSUB Execute a dialplan subroutine. This will perform in the same way as the GoSub() dialplan application. When the HANGUP AGI command is used, the channel is not immediately hung up. Instead, the channel is marked as needing to be hung up.
Command: VERBOSE "Puppies like cotton candy." 1 Response: Success ActionID: my-action-id Message: Added AGI command to queue Event: AsyncAGI Privilege: agi,all SubEvent: Exec Channel: SIP/0004F2060EB4-00000013 CommandID: my-command-id Result: 200%20result%3D1%0A The following output is what was seen on the Asterisk console during this async AGI session: -- Executing [7011@phones:1] AGI("SIP/0004F2060EB4-00000013", "agi:async") in new stack agi:async: Puppies like cotton candy.
will send a line containing the word HANGUP. If you would like to disable having Asterisk send the SIGHUP signal to your process-based AGI application or the HANGUP string to your FastAGI server, you can do so by setting the AGISIGHUP channel variable, as demonstrated in the following short example: ; ; Don't send SIGHUP to an AGI process ; or the "HANGUP" string to a FastAGI server.
Table 21-3. AGI development frameworks Framework Language URL Adhearsion Ruby http://adhearsion.com/ StarPy Python http://starpy.sourceforge.net/ Asterisk-Java Java http://asterisk-java.org/ Asterisk-perl Perl http://asterisk.gnuinter.net/ PHPAGI PHP http://phpagi.sourceforge.net/ Conclusion AGI provides a powerful interface to Asterisk that allows you to implement first-party call control in the programming language of your choice.
CHAPTER 22 Clustering You cannot eat a cluster of grapes at once, but it is very easy if you eat them one by one. —Jacques Roumain The word “clustering” can mean different things to different people. Some people would say clustering is simply having a replicated system on standby available to be turned on when the primary system fails. To others, clustering is having several systems working in concert with one another, with replicated data, fully redundant, and infinitely expandable.
functions such as voicemail and conferencing being provided through external modules that may cost thousands of dollars. This topology is illustrated in Figure 22-1. Figure 22-1. Traditional call center Such systems will utilize a set of rules for delivering calls to agents through the standard automatic call distribution (ACD) rules, and will have little flexibility.
Figure 22-2. Remote hybrid system to or from the CO, either Asterisk will deliver calls from the PRI through itself and to the existing PBX, or the existing PBX will send calls over the PRI connection to Asterisk, which will then direct the calls to the new endpoints (phones). With Asterisk in the picture, functionality can be moved piecemeal from the existing PBX system over to Asterisk, which can take on a greater role and command more of the system over time.
over time, limiting interruptions to the business and taking a more gradual approach to training users. Pure Asterisk, Nondistributed The next step in our journey is the pure Asterisk system. In this system we’ve successfully migrated away from the existing PBX system and are now handling all functionality through Asterisk. Our existing PRI has been attached to Asterisk, and we’ve expanded our capacity by integrating an Internet Telephony Service Provider (ITSP) into our system.
systems, electrical grids, and Internet connections, the company can save a significant amount of money by supporting remote employees. Additionally, those employees can be located across the globe to expand the number of hours your agents are available, thereby allowing you to serve more time zones. Using this system is simple and efficient, but as the company grows, the system may reach a capacity issue. We’ll look at how the system can be expanded later in this chapter.
Figure 22-4. Asterisk database integration, single server our data is abstracted outside of Asterisk, we can use applications such as unison (http://www.cis.upenn.edu/~bcpierce/unison/) or rsync to keep the configuration files synchronized between the primary and the backup system. We could also use subversion or git to track changes to the configuration files, making it easy to roll back changes that don’t work out.
Replicated Databases Using a replicated database provides some redundancy in the backend to help limit the amount of downtime callers and agents experience if a database failure occurs. A master-master database configuration is required so that data can be written to either database and be automatically replicated to the other system, ensuring that we have an exact copy of the data on two physical machines.
specify the preferred order for database connections in case one fails. In func_odbc, you can even specify different servers for reading data and writing data through the dialplan functions you create. All of this flexibility allows you to provide a system that works well for your business. External programs can also be used for controlling failover between systems. The pen application (http://siag.
Figure 22-6. Device state distribution with OpenAIS systems to live on low-latency links, which typically means they all need to reside in the same physical location, attached to the same switch. That said, while the OpenAIS library does not work across physically separate networks, it does allow a Queue() to reside on one system and queue members to reside on another system (or multiple systems).
wide area networks, we can now have Asterisk systems at different physical locations distribute device state information to each other (see Figure 22-7). With the OpenAIS implementation, the library would be used on each system, enabling them to distribute device state information. In the XMPP scenario, a central server (or cluster of servers) is used to distribute the state among all of the Asterisk boxes in the cluster. Currently the best application for doing this is the Tigase XMPP server (http://www.
Download from Wow! eBook The advantage to XMPP device state distribution is that it is possible to distribute state to multiple physical locations, which is not possible with OpenAIS. The disadvantage is that it is more complex to set up (since you need an external service running the Tigase XMPP server) than the OpenAIS implementation. More information about configuring distributed device states with XMPP can be found in “Using XMPP” on page 314.
Figure 22-8. Distributed queue infrastructure Asterisk system, and then another caller enters the sales queue on box two, no information will be distributed between those queues to indicate who is first and who is second in line. The two queues are effectively separate. Perhaps future versions of Asterisk will have the ability to do that, but at this time it is not supported. We mention this so you can plan your system accordingly.
Conclusion In this chapter we explored how you can transition a traditional (non-Asterisk) telephony system into a distributed call center. Along the way, we’ve seen how a call center with just a few seats can grow into a system with hundreds of seats in different physical locations. While the ability to grow your business and plan for the future is crucial, it is also important to not build a system that is more complex than it needs to be.
CHAPTER 23 Distributed Universal Number Discovery (DUNDi) A community is like a ship; everyone ought to be prepared to take the helm. —Henrik Ibsen Distributed Universal Number Discovery, or DUNDi, is a service discovery protocol that can be used for locating resources at remote locations. The original intention of DUNDi was to permit decentralized routing among many peers using a General Peering Agreement (GPA). The GPA (available at http://dundi.com/PEERING.
Figure 23-1. DUNDi peer-to-peer request system Bob asks Sally if she knows how to reach the requested extension, and she responds with, “You can reach that extension at IAX2/dundi:very_long_password@hostname/ extension.” Bob then stores the address in his database and passes on to you the information about how to reach 4001. With the newfound information, you can then make a separate request to actually place the call to Sally’s box in order to reach extension 4001.
by requesting the extension numbers from the remote location when your local box doesn’t know how to reach them. Additionally, if one of the locations had a cheaper route to a PSTN number you wanted to dial, you could request that route in your DUNDi cloud. For example, if one box was located in Vancouver and the other in Toronto, the Vancouver office could send calls destined for the Toronto area across the network using VoIP and out the PRI in Toronto, so they can be placed locally on the PSTN.
Option Description autokill Used to control how long we wait for an ACK to our DPDISCOVER. Setting this timeout prevents the lookups from stalling due to a latent peer. This can be yes, no, or a numeric value representing the number of milliseconds to wait. You can use the qualify option to enable this per-peer. secretpath A rotating key is created and stored within the AstDB. The value is stored in the key ’secret’ under the family defined by secretpath.
Option Description include Used to control whether this peer is included in searches for the mapping defined. Can be set to the value of all if used for all mappings. noinclude Used to control whether this peer is excluded from searches for the mapping defined. Can be set to all if this peer should be excluded from all lookups. permit Used to control whether this peer can perform lookups against a particular mapping. If the value is set to all, this peer can search against all defined mappings.
country=CA email=support@toronto.example.com phone=+14165551212 ; ; Specify bind address and port number. ;bindaddr=0.0.0.0 port=4520 entityid=FF:FF:FF:FF:FF:FF ttl=32 autokill=yes ;secretpath=dundi Default is port 4520. The entity identifier defined by entityid should generally be the Media Access Control (MAC) address of an interface in the machine.
; Specify bind address and port number. ;bindaddr=0.0.0.0 port=4520 entityid=00:00:00:00:00:00 ttl=32 autokill=yes ;secretpath=dundi Default port is 4520. In the next section we’ll create our initial DUNDi peers. Initial DUNDi Peer Definition A DUNDi peer is identified by the unique layer-two MAC address of an interface on the remote system. The dundi.
Vancouver server in /var/lib/asterisk/keys/ and place the vancouver.pub file on the Toronto server in the same location. After downloading the keys, we must reload the res_crypto.so and pbx_dundi.so modules in Asterisk: toronto*CLI> module reload res_crypto.so -- Reloading module 'res_crypto.so' (Cryptographic Digital Signatures) -- Loaded PUBLIC key 'vancouver' -- Loaded PUBLIC key 'toronto' -- Loaded PRIVATE key 'toronto' vancouver*CLI> module reload res_crypto.so -- Reloading module 'res_crypto.
When you create a peer, you need to define which mapping contexts you will allow this peer to search. You do this with the permit statement (each peer may contain multiple permit statements). Mapping contexts are related to dialplan contexts in the sense that they are a security boundary for your peers. We’ll enable our mapping in the next section.
${NUMBER} The number being requested. ${IPADDR} The IP address to connect to. It is generally safest to statically configure the hostname, rather than make use of the ${IPADDR} variable. The ${IPADDR} variable will sometimes reply with an address in the private IP space, which is unreachable from the Internet. With our mapping configured, let’s create a simple dialplan context against which we can perform lookups for testing. We’ll make this more dynamic in “Controlling Responses” on page 516.
Since we only have a single mapping defined (extensions), we’re going to permit and include extensions within our peer definitions on both the Toronto and Vancouver systems. On Toronto, we’ll permit Vancouver to search the extensions mapping, and use Vancouver whenever we’re performing a lookup within the extensions mapping: [00:00:00:00:00:00] ; Vancouver Remote Office model = symmetric host = vancouver.example.
We’ve added the keyword bypass to the end of the lookup in order to bypass the cache (in case we wish to perform several tests): vancouver*CLI> dundi lookup 1000@extensions bypass 1. 0 SIP/dundi:very_secret_secret@172.16.0.161/1000 (EXISTS) from ff:ff:ff:ff:ff:ff, expires in 3600 s DUNDi lookup completed in 12 ms The response of SIP/dundi:very_secret_secret@172.16.0.161/1000 gives us an address that we can use to call extension 1000.
toronto*CLI> sip reload To accept the incoming calls, define the [DUNDi_Incoming] context in extensions.conf and add the following to the Toronto system’s dialplan. [DUNDi_Incoming] exten => 1000,1,Verbose(2,Incoming call from the DUNDi peer) same => n,Answer() same => n,Playback(silence/1) same => n,Playback(tt-weasels) same => n,Hangup() Reload the dialplan with dialplan reload after saving your changes to extensions.conf.
Controlling Responses Responses are controlled with the dialplan. Whenever an incoming request matches the dialplan configured for the mapping (whether the request is for a specific extension or a pattern match), a response will be sent. If the request does not match within the dialplan, no response is sent. In the example we’ve been building, the extension 1000 is the only extension that can be matched and thus generate a response.
We could also advertise a full or partial range of extensions using pattern matches: [RegisteredDevices] exten => _1[1-3]XX,1,NoOp() ; extensions 1100->1399 exten => _1[7-9]XX,1,NoOp() ; extensions 1700->1999 Pattern matches are a good way of adding ranges of numbers, but these are still static. In the next section we’ll explore how we can add some fluidity to the RegisteredDevices context.
Because the other end is just going to request an extension number and won’t necessarily know the location of the device on our system, we can use the DB() and DB_EXISTS() functions within the mapping to perform a lookup from our AstDB for the device to call.† Prior to Asterisk version 1.8.3, the maximum length of the destina tion field (see “Creating Mapping Contexts” on page 510) was 80 characters, which made the use of nested dialplan functions nearly impossible. As of Asterisk 1.8.
our example) using the DB() function. To determine which value the IF() function will return, we use the DB_EXISTS() function. This function checks whether a value exists at phones/${NUMBER}/device within the AstDB, and returns either 1 or 0 (true or false). The DB_EXISTS() function not only returns 1 or 0, but also sets the $ {DB_RESULT} channel variable that contains the value inside the database if the return value is 1.
same => n,Verbose(2,The result of the lookup was ${DUNDi_Result}) same => n,Hangup() The arguments passed to DUNDILOOKUP() are: extension,context,options. Only one option, b, is available for the DUNDILOOKUP() function, and that is used to bypass the local cache. The advantage to using the DUNDILOOKUP() function is that it is straightforward and easy to use. The disadvantage is that it will only set the first value returned; if multiple values are returned, they will be discarded.
; End of our loop same => n,EndWhile() same => n,Playback(silence/1) same => n,Playback(vm-goodbye) same => n,Hangup() ; If no results were found, execute this dialplan exten => NoResults,1,Verbose(2,No results were found) same => n,Playback(silence/1) same => n,Playback(invalid) same => n,Hangup() Our example dialplan performs a lookup using the DUNDIQUERY() function and stores the resulting ID value in the DUNDI_ID channel variable.
same => n,Set(thisResult=${DUNDIRESULT(${DUNDI_ID},${ResultCounter})}) ; If the current value returned is not None, we have a resulting ; location to call and we can exit the loop same => n,ExecIf($["${thisResult}" != "None"]?ExitWhile()) ; If we made it this far, no value has been returned yet that we want to ; use, so increase the counter and try the next value.
CHAPTER 24 System Monitoring and Logging Chaos is inherent in all compounded things. Strive on with diligence. —The Buddha Asterisk comes with several subsystems that allow you to obtain detailed information about the workings of your system. Whether for troubleshooting or for tracking usage for billing or staffing purposes, Asterisk’s various monitoring modules can help you keep tabs on the inner workings of your system. logger.
There is a sample logger.conf file that comes with the Asterisk source, but rather than just copying over the sample file, we recommend that you use the following for your initial logger.
a b Type Description debug Debugging is only useful if you are troubleshooting a problem with the Asterisk code itself. You would not use debug to troubleshoot your dialplan, but you would use it if the Asterisk developers asked you to provide logs for a problem you were reporting. Do not use debug in production, as the amount of detail stored can fill up a hard drive in a matter of days.
exited non-zero on 'Zap/1-1' [Mar 11 09:39:35] VERBOSE[2973] logger.c: [Mar 11 09:39:35] VERBOSE[3680] logger.c: [Mar 11 09:39:35] VERBOSE[31362] logger.c: -- Hungup 'Zap/1-1' -- Starting simple switch on 'Zap/1-1' -- Hungup 'Zap/1-1' To filter on one call specifically, we could grep on the thread ID. For example: $ grep 31362 verbose which would give us: [Mar 11 09:38:35] VERBOSE[31362] logger.c: [Mar 11 09:39:35] VERBOSE[31362] logger.
Verifying Logging You can view the status of all your logger.conf settings through the Asterisk CLI by issuing the command: *CLI> logger show channels You should see output similar to: Channel ------syslog.
a Option Value/Example Notes lastdata SIP/0004F2046969,30,tT The arguments passed to the lastapp. This field is set automatically and is read-only. start 2010-10-26 12:00:00 The start time of the call. This field is set automatically and is readonly. answer 2010-10-26 12:00:15 The answered time of the call. This field is set automatically and is read-only. end 2010-10-26 12:03:15 The end time of the call. This field is set automatically and is readonly.
To view the built-in documentation for the CDR() function, run the following command at the Asterisk console: *CLI> core show function CDR In addition to the CDR() function, there are some dialplan applications that may be used to influence CDR records. We’ll look at these next. Dialplan Applications There are a few dialplan applications that can be used to influence CDRs for the current call.
a Option Value/ Example Notes batch no Queue up CDRs to be logged in batches instead of logging synchronously at the end of every call. This prevents CDR logging from blocking the completion of the call teardown process within Asterisk. The default value is no, but we recommend turning it on.a size 100 Set the number of CDRs to queue up before they are logged during batch mode. The default value is 100.
[mytable] connection = asterisk table = asterisk_cdr A more detailed example of setting up a database for logging CDRs can be found in “Storing Call Detail Records (CDRs)” on page 375. Table 24-4 lists the options that can be specified in a table configuration section in the cdr_adaptive_odbc.conf file. Table 24-4. cdr_adaptive_odbc.conf table configuration options Option Value/Example Notes connection pgsql1 The database connection to be used.
cdr_csv The cdr_csv module is a very simple CDR backend that logs CDRs into a CSV (comma separated values) file. The file is /var/log/asterisk/cdr-csv/Master.csv. As long as CDR logging is enabled in cdr.conf and this module has been loaded, CDRs will be logged to the Master.csv file. While no options are required to get this module working, there are some options that customize its behavior. These options, listed in Table 24-5, are placed in the [csv] section of cdr.conf. Table 24-5. cdr.
${CSV_QUOTE(${CDR(end)})},${CSV_QUOTE(${CDR(duration)})}, ${CSV_QUOTE(${CDR(billsec)})},${CSV_QUOTE(${CDR(disposition)})}, ${CSV_QUOTE(${CDR(amaflags)})},${CSV_QUOTE(${CDR(accountcode)})}, ${CSV_QUOTE(${CDR(uniqueid)})},${CSV_QUOTE(${CDR(userfield)})} In the actual configuration file, the value in the Master.csv mapping should be on a single line. cdr_manager The cdr_manager backend emits CDRs as events on the Asterisk Manager Interface (AMI), which we discussed in detail in Chapter 20.
Download from Wow! eBook CallerID: Channel: Console/dsp DestinationChannel: LastApplication: Hangup LastData: StartTime: 2010-08-23 08:27:21 AnswerTime: 2010-08-23 08:27:21 EndTime: 2010-08-23 08:27:21 Duration: 0 BillableSeconds: 0 Disposition: ANSWERED AMAFlags: DOCUMENTATION UniqueID: 1282570041.3 UserField: Rate: 0.02 Carrier: BS&S cdr_mysql This module allows posting of CDRs to a MySQL database. We recommend that new installations use cdr_adaptive_odbc instead.
cdr_sqlite This module allows posting of CDRs to a SQLite database using SQLite version 2. Unless you have a specific need for SQLite version 2 as opposed to version 3, we recommend that all new installations use cdr_sqlite3_custom. This module requires no configuration to work. If the module has been compiled and loaded into Asterisk, it will insert CDRs into a table called cdr in a database located at /var/log/asterisk/cdr.db.
The Asterisk module has a configuration file, as well. Add the following section to /etc/ asterisk/cdr_syslog.conf: [cdr] facility = local4 priority = info template = "We received a call from ${CDR(src)}" Here is an example syslog entry using this configuration: $ cat /var/log/asterisk/asterisk-cdr.log Aug 12 19:17:36 pbx cdr: "We received a call from 2565551212" cdr_tds The cdr_tds module uses the FreeTDS library to post CDRs to a Microsoft SQL Server or Sybase database.
Here is the CDR that was logged to Master.csv as a result of this call: """Console"" <2565551212>","2565551212","101","LocalSets","Console/dsp", "SIP/0000FFFF0002-00000000","Dial","SIP/0000FFFF0002","2010-08-16 01:16:10", "2010-08-16 01:16:16","2010-08-16 01:16:29","19","13","ANSWERED", "DOCUMENTATION","","1281935770.2","",2 Caveats The CDR system in Asterisk works very well for fairly simple call scenarios.
CEL event type Description CHAN_END occurs after Asterisk has completed post-call cleanup and all resources associated with that channel have been released. APP_START A tracked application has started executing on a channel. Tracked applications are set in the main CEL configuration file, which is covered in “cel.conf” on page 540. APP_END A tracked application has stopped executing on a channel. PARK_START A channel has been parked. PARK_END A channel has left the parking lot.
Channel Event Contents Each CEL event contains the fields listed in Table 24-9: Table 24-9. CEL event fields Field name Value/Example Notes eventtype CHAN_START The name of the event. The list of events that may occur can be found in Table 24-7. eventtime 2010-08-19 07:27:19 The time that the event occurred. cidname Julie Bryant The caller ID name set on the channel associated with this event. cidnum 18435551212 The caller ID number set on the channel associated with this event.
Dialplan Applications The CEL system includes a single dialplan application that lives in the app_celgenuserevent.so module. This application is used to generate custom user-defined events of the type EV_USER_EVENT.
cel.conf, which were described in the previous section, these modules require configuration to make them operate. cel_odbc The cel_odbc.so module provides the ability to log CEL events to a database using ODBC. This module is not quite as adaptive as the CDR adaptive ODBC backend. For CEL events, there are no custom variables.
• userfield • peer Table 24-11 shows the mapping between event types and their integer values that will be inserted into the eventtype column of the database. Table 24-11.
Table 24-12 shows the options that can be specified in a table configuration section in the cel_odbc.conf file. Table 24-12. cel_odbc.conf table configuration Option Value/Example Notes connection pgsql1 Specifies the database connection to be used. This is a reference to the configured connection in res_odbc.conf. This field is required. table asterisk_cdr Specifies the table name. This field is required. usegmtime no Enables/disables logging of timestamps using GMT instead of local time.
The following example shows a sample configuration for cel_custom that enables a single CEL log file, Master.csv. This file will be created as /var/log/asterisk/cel-custom/ Master.csv. The template that has been defined uses the CHANNEL(), CALLERID(), and CSV_QUOTE() dialplan functions. The CSV_QUOTE() function ensures that the values are properly escaped for the CSV file format. This example also references some special CEL variables, which are listed in Table 24-13. Table 24-13.
With this configuration in place, CEL events will appear as events on the manager interface.
cel_sqlite3_custom This CEL backend inserts CEL events into a SQLite database using SQLite version 3. The database created by this module lives at /var/log/asterisk/master.db. The configuration file for this module, /etc/asterisk/cel_sqlite3_custom.conf, identifies the table name, as well as customizes which CEL variables will be inserted into the database. It looks like this: [master] table = cel ; ; List the column names to use when inserting CEL events.
apps = Dial,Playback events = ALL Single-party call In this example, a single phone calls into an extension that plays back a prompt that says “Hello World.” This is the dialplan: exten => 200,1,Answer() same => n,Playback(hello-world) same => n,Hangup() Here are the CEL events that are logged as a result of making this call: "CHAN_START","1282062437.436130","Julie Bryant","12565553333","","","","200", "LocalSets","SIP/0000FFFF0003-00000010","","","3","","1282062437.17", "1282062437.
"APP_START","1282062455.574872","Julie Bryant","12565553333","12565553333","", "101","101","LocalSets","SIP/0000FFFF0003-00000011","Dial", "SIP/0000FFFF0001","3","","1282062455.18","1282062455.18","","" "CHAN_START","1282062455.575044","Candice Yant","12565551111","","","","s", "LocalSets","SIP/0000FFFF0001-00000012","","","3","","1282062455.19", "1282062455.18","","" "ANSWER","1282062458.
exten => 101,1,Dial(SIP/0000FFFF0001) exten => 102,1,Dial(SIP/0000FFFF0002) Here are the CEL events logged as a result of this call scenario: "CHAN_START","1282062488.028200","Julie Bryant","12565553333","","","", "102","LocalSets","SIP/0000FFFF0003-00000013","","","3","", "1282062488.20","1282062488.20","","" "APP_START","1282062488.028464","Julie Bryant","12565553333","12565553333", "","102","102","LocalSets","SIP/0000FFFF0003-00000013","Dial", "SIP/0000FFFF0002","3","","1282062488.20","1282062488.
"3","","1282062488.21","1282062488.20","","" "APP_END","1282062497.941415","Julie Bryant","12565553333","12565553333","", "102","102","LocalSets","SIP/0000FFFF0003-00000013","Dial", "SIP/0000FFFF0002","3","","1282062488.20","1282062488.20","","" "HANGUP","1282062497.941453","Julie Bryant","12565553333","12565553333", "","102","102","LocalSets","SIP/0000FFFF0003-00000013","","","3","", "1282062488.20","1282062488.20","","" "CHAN_END","1282062497.
SNMP The Simple Network Management Protocol (SNMP) is a standardized protocol for network management. It is very commonly used and implemented across many applications and network devices. Platforms such as OpenNMS,§ an open source network management platform, use SNMP (among other things). Asterisk supports SNMP through the res_snmp module. This section discusses the installation and configuration of res_snmp, as well as how it can be utilized by a platform like OpenNMS.
$ $ $ $ cd /usr/src/asterisk-complete/asterisk/1.8/ ./configure make menuselect # verify that res_snmp is selected under Resource Modules sudo make install You then need to copy the sample config file over to the /etc/asterisk folder: $ sudo cp /usr/src/asterisk-complete/asterisk/1.8/configs/res_snmp.conf.sample \ /etc/asterisk/res_snmp.conf We’ll talk about configuring this file for use with OpenNMS in the next section.
Editing /etc/asterisk/res_snmp.conf to work with your OpenNMS server In the /etc/asterisk/res_snmp.conf file that you’ve copied over from your source directory, there are two lines you must uncomment: [general] ;subagent=yes ;enabled=yes Modify the res_snmp.conf file so both the SNMP client and the subagent are enabled: [general] subagent=yes enabled=yes After modifying this file, you will need to reload the res_snmp.so module in order for the changes to take effect: *CLI> module unload res_snmp.
syscontact Leif Madsen lmadsen@shifteight.org Ctrl + D The syslocation and syscontact lines are not necessary, but they can make it easier to identify a particular server if you’re monitoring several nodes. Now we need to enable the AgentX subagent support so information about our Asterisk system can be found: $ sudo cat >> snmpd.conf master agentx agentXSocket /var/agentx/master agentXPerms 0660 0775 nobody root sysObjectID .1.3.6.1.4.1.22736.
and have access to the Asterisk statistics. You should be able to click on Resource Graphs after selecting the node you created and see a selection of graphs available, such as SIP, DAHDI, Local, etc. Enabling SNMPv3 Enabling SNMPv3 allows you to securely connect and transmit data from the SNMP daemon to the SNMP client. This may not be necessary in a local environment, especially if the client and the daemon are running on the same machine.
will clone the opennmsUser user from the initial user. We configured the password setup_passphrase for the authentication and privacy settings when we added the ini- tial user to the /var/net-snmp/snmpd.conf file: $ sudo snmpusm -v3 -u initial -n "" -l authPriv \ -a MD5 -A setup_passphrase \ -x DES -X setup_passphrase \ localhost create opennmsUser initial User successfully created.
com2sec notConfigUser default #group #group group notConfigGroup v1 notConfigGroup v2c notConfigGroup usm #view #view view systemview systemview all public notConfigUser notConfigUser opennmsUser included included included #access notConfigGroup "" access notConfigGroup "" .1.3.6.1.2.1.1 .1.3.6.1.2.1.25.1.1 .1 any usm noauth priv exact all exact all none none none none syslocation Caledon, ON syscontact Leif Madsen lmadsen@shifteight.
-x DES -X 0p3nNMSv3 \ localhost .1.3.6.1.4.1.22736 If all goes well, you should get lots of lines back, including: SNMPv2-SMI::enterprises.22736.1.5.4.1.2.1 SNMPv2-SMI::enterprises.22736.1.5.4.1.2.2 SNMPv2-SMI::enterprises.22736.1.5.4.1.2.3 SNMPv2-SMI::enterprises.22736.1.5.4.1.2.4 SNMPv2-SMI::enterprises.22736.1.5.4.1.2.5 SNMPv2-SMI::enterprises.22736.1.5.4.1.2.6 SNMPv2-SMI::enterprises.22736.1.5.4.1.3.1 SNMPv2-SMI::enterprises.22736.1.5.4.1.3.2 SNMPv2-SMI::enterprises.22736.1.5.4.1.3.
Figure 24-2 shows a graph of active channels of a specific type. In this case, we’re looking at how many DAHDI channels are active on the system. Monitoring DAHDI channels is particularly interesting, since DAHDI channels are generally mapped to physical resources, and a predefined number of channels are available. It would be very useful to monitor DAHDI channel utilization and get notified when usage passes a particular threshold, as this might be a signal that additional capacity needs to be added.
CHAPTER 25 Web Interfaces A point of view can be a dangerous luxury when substituted for insight and understanding. —Marshall McLuhan Before you get too excited, this chapter is not going to talk about dialplan configuration GUIs such as FreePBX or Digium’s Asterisk-GUI. We recognize that much of the success of Asterisk is due to the success of FreePBX-based projects such as AsteriskNOW, Trixbox, and PBX in a Flash, but in this book our focus is on Asterisk.
What we will do in this chapter is introduce a few projects that provide web interfaces into other parts of the system, and a selection of web-driven applications that are significant, useful, or recommended. In general, we have tended to focus on free and open source applications, but we will mention some commercial products where we feel it’s warranted. There are many third-party applications that have been developed for Asterisk. The ones described here are among the best, at the time of this writing.
Queue Status Display Queue status will often be displayed on a large, wall-mounted panel or a reader board.
want excellent reporting capabilities, you will find a huge industry with many experienced participants. For a simple interface to the call records, a popular program is CDR-Stats, which is the successor to the hugely popular Asterisk-Stat package. This open source reporting interface provides a simple way to examine call detail records, and some basic metrics on calling patterns.
CHAPTER 26 Security We spend our time searching for security and hate it when we get it. —John Steinbeck Security for your Asterisk system is critical, especially if the system is exposed to the Internet. There is a lot of money to be made by attackers in exploiting systems to make free phone calls. This chapter provides advice on how to provide stronger security for your VoIP deployment.
'"12345"' failed for '203.86.167.220:5061' - No matching peer found [Aug 22 15:17:15] NOTICE[25690] chan_sip.c: Registration from '"123456"' failed for '203.86.167.220:5061' - No matching peer found [Aug 22 15:17:15] NOTICE[25690] chan_sip.c: Registration from '"test"' failed for '203.86.167.220:5061' - No matching peer found [Aug 22 15:17:15] NOTICE[25690] chan_sip.c: Registration from '"sip"' failed for '203.86.167.
These account scans take advantage of the fact that the response that comes back from the server for a registration attempt will differ depending on whether or not the account exists. If the account exists, the server will request authentication. If the account does not exist, the server will immediately deny the registration attempt. This behavior is just how the protocol is defined.
Installation Fail2ban is available as a package in many distributions. Alternatively, you can install it from source by downloading it from the Fail2ban website. To install it on Ubuntu, use the following command: $ sudo apt-get install fail2ban To install Fail2ban on CentOS, you must have the EPEL repository enabled. For more information on the EPEL repository, see “Third-Party Repositories” on page 46.
$ sudo apt-get install postfix To install Postfix on CentOS, use this command: $ sudo yum install postfix To test the installation of your MTA, you can send a quick email using mutt. To install it, use the same installation commands as given for installing Postfix, but substitute mutt for the package name. Then run the following commands to test the MTA: $ echo "Just testing." > email.txt $ mutt -s "Testing" youraddress@shifteight.org < email.
NOTICE.* .*: Registration from '.*' failed for '' # - No matching peer found NOTICE.* .*: Registration from '.*' failed for '' # - Username/auth name mismatch NOTICE.* .*: Registration from '.*' failed for '' # - Device does not match ACL NOTICE.* NOTICE.* NOTICE.* NOTICE.* failed to authenticate as '.*'$ .*: No registration for peer '.*' \(from \) .*: Host failed MD5 authentication for '.*' (.*) .*: Failed to authenticate user .*@.
[DEFAULT] # Multiple addresses can be specified, separated by a space. ignoreip = 127.0.0.1 10.1.1.1 destemail = youraddress@shifteight.org Encrypted Media Be aware that the audio for a Voice over IP call is typically transmitted in an unencrypted format. Anyone that can capture the traffic can listen to the audio of the phone call. Luckily, Asterisk supports encrypting the media of VoIP calls. If you are using SIP, you can encrypt the media using SRTP. IAX2 supports fully encrypting calls, as well.
A call like this is an attempt at exploiting a dialplan injection vulnerability. In the previous extension definition, once ${EXTEN} has been evaluated, the actual Dial() statement that will be executed is: exten => _X.,1,Dial(IAX2/otherserver/1234&DAHDI/g1/12565551212,30) If the system has a PRI configured, this call will cause a call to go out on the PRI to a number chosen by the attacker, even though you did not explicitly grant access to the PRI to that caller.
an extension to the dialplan that runs the System() application, enabling it to run any command it wants. If it also has access to originate calls, it can originate a call to that extension, resulting in the execution of that command. Be careful when opening up AMI access on your system and restrict what permissions are granted to each account in /etc/asterisk/manager.conf. Tip #9: Secure Asterisk network APIs. Use firewall rules to restrict access to your FastAGI server. Use encryption on the AMI.
192.168.1.0/255.255.255.0 = 1024 [some_peer] ; A dynamic peer's address is not known until that peer ; registers. A call number limit can be specified in the ; peer's section instead of the callnumberlimits section.
good idea to set ACLs to ensure that only devices on your local network can use the accounts for the phones. Here is an example of doing that in /etc/asterisk/sip.conf: [phoneA] ; Use a better account name than this. type = friend ; Start by denying everyone. deny = 0.0.0.0/0.0.0.0 ; Allow connections that originate from 192.168.X.X to attempt ; to authenticate against this account. permit = 192.168.0.0/255.255.0.
Download from Wow! eBook One of the most popular tools for SIP account scanning and password cracking is SIPVicious. We strongly encourage that you take a look at it and use it to audit your own systems. If your system is exposed to the Internet, others will likely run it against your system, so make sure that you do it first. Another resource for all things VoIP security–related is the VOIPSEC mailing list on VOIPSA.org. The website contains some additional resources, as well.
CHAPTER 27 Asterisk: A Future for Telephony Now this is not the end. It is not even the beginning of the end. But it is, perhaps, the end of the beginning. —Winston Churchill We have arrived at the final chapter of this book. We’ve covered a lot, but we hope that we have made it clear that this book has merely scratched the surface of this phenomenon called Asterisk. To wrap things up, we want to spend some time exploring what we might see from Asterisk and open source telephony in the near future.
It’s interesting to contrast the history of the telephone with the history of Linux and the Internet. While the telephone was created as a commercial exercise, and the telecom industry was forged through lawsuits and corporate takeovers, Linux and the Internet arose out of the academic community, which has always valued the sharing of knowledge over profit. The cultural differences are obvious.
consistently. Each manufacturer desires a total monopoly, so the concept of interoperability tends to take a back seat to being first to market with a creative new idea. The ISDN protocols are a classic example of this. Deployment of ISDN was (and in many ways still is) a painful and expensive proposition, as each manufacturer decided to implement it in a slightly different way. ISDN could very well have helped to usher in a massive public data network, 10 years before the Internet.
is not familiar to the telecom industry, and very well might not be until open source products such as Asterisk begin to transform the fundamental nature of the industry. This is a revolution similar to the one Linux and the Internet willingly started over 10 years ago (and IBM unwittingly started with the PC, 15 years before that). What is this revolution? The commoditization of telephony hardware and software, enabling a proliferation of tailor-made telecommunications systems.
The fact that a customer might only need five out of five hundred features is ignored, and that customer’s desire to have five unavailable features that address the needs of his business is dismissed as unreasonable.‖ Until flexibility becomes standard, telecom will remain stuck in the last century—all the VoIP in the world notwithstanding. Asterisk addresses that problem directly, and solves it in a way that few other telecom systems can.
Standards Compliance In the past few years, it has become clear that standards evolve at such a rapid pace that to keep up with them requires an ability to quickly respond to emerging technology trends. Asterisk, by virtue of being an open source, community-driven development effort, is uniquely suited to the kind of rapid development that standards compliance demands. Asterisk does not focus on cost-benefit analysis or market research.
Figure 27-1. Asterisk as a PBX gateway Here are some of the options you can implement: Keep your old PBX, but evolve to IP Companies that have spent vast sums of money in the past few years buying proprietary PBX equipment want a way out of proprietary jail, but they can’t stomach the thought of throwing away all of their otherwise functioning equipment.
Figure 27-2. Find-me-follow-me Figure 27-3. VoIP-enabling a legacy PBX callers to be transferred to extensions, and it is built into most proprietary voicemail systems—but IVR can be so much more. IVR systems are generally very expensive, not only to purchase, but also to configure. A custom IVR system will usually require connectivity to an external database or application.
Here are a few examples of relatively simple IVRs an Asterisk system could be used to create: Weather reporting Using the Internet, you can obtain text-based weather reports from around the world in a myriad of ways. Capturing these reports and running them through a purpose-built parser (Perl would probably eat this up) would allow the information to be available to the dialplan.
Home automation Asterisk is still too much of an über-geek’s tool to be able to serve in the average home, but with no more than average Linux and Asterisk skills, the following things become plausible: Monitoring the kids Parents who want to check up on the babysitter (or the kids home alone) could dial an extension context protected by a password. Once authenticated, a two-way audio connection would be created to all the IP phones in the house, allowing Mom and Dad to listen for trouble. Creepy? Yes.
Speech Processing The dream of having our technical inventions talk to us is older than the telephone itself. Each new advance in technology spurs a new wave of eager experimentation. Generally, results never quite meet expectations, possibly because as soon as a machine says something that sounds intelligent, most people assume that it is intelligent. People who program and maintain computers realize their limitations, and thus tend to allow for their weaknesses.
Asterisk, you can make voice-driven menus and IVR systems in record time! For more information, see http://www.lumenvox.com. High-Fidelity Voice As we gain access to more and more bandwidth, it becomes less and less easy to understand why we still use low-fidelity codecs. Many people do not realize that Skype provides higher fidelity than a telephone; it’s a large part of the reason why Skype has a reputation for sounding so good.
Why we love videoconferencing Videoconferencing promises a richer communications experience than the telephone. Rather than simply hearing a disembodied voice, you have access to all the nuances of speech that come from face-to-face communication. Why videoconferencing may never totally replace voice There are some challenges to overcome, though, and not all of them are technical.
Unified Messaging This is a term that has been hyped by the telecom industry for years, but adoption has been far slower than predicted. Unified messaging refers to the concept of tying voice and text-messaging systems into one. With Asterisk, the two don’t need to be artificially combined, as Asterisk already treats them the same way.
Now that calls are hopping from PSTN to Internet to who-knows-what, some consideration must be given to E.164. ENUM In response to this challenge, the IETF has sponsored the Electronic NUmber Mapping (ENUM) working group, the purpose of which is to map E.164 numbers into the Domain Name System (DNS). While the concept of ENUM is sound, it requires cooperation from the telecom industry to achieve success. However, cooperation is not what the telecom industry is famous for, and thus far ENUM has foundered.
VoIP spam Yes, it’s coming. There will always be people who believe they have the right to inconvenience and harass others in their pursuit of money. Efforts are under way to try to address this, but only time will tell how efficacious they will be. Fear, uncertainty, and doubt The industry is making the transition from ignorance to laughter. If Gandhi is correct, we can expect the fight to begin soon.
identify its physical location, an emergency call from it will provide no clue as to where the caller is. VoIP creates similar challenges. Call monitoring for law enforcement agencies Law enforcement agencies have always been able to obtain wiretaps on traditional circuit-switched telephone lines. While regulations are being enacted that are designed to achieve the same end on the network, the technical challenges of delivering this functionality will probably never be completely solved.
Complexity Open systems require new approaches to solution design. Just because the hardware and software are cheap doesn’t mean the solution will be. Asterisk does not come out of the box ready to run; an Asterisk system has to be designed and built, and then maintained. While the base software is free, and the hardware costs will be based on commodity pricing, it is fair to say that the configuration costs for a highly customized system will be a sizable part of the overall solution cost.
creative skills will now actually serve the needs of their customers, rather than being focused on managing kludge. Proper integration of communications technologies Ultimately, the promise of open source comes to nothing if it cannot fulfill the need people have to solve problems. The closed industries lost sight of the customer, and tried to fit the customer to the product. Open source telephony brings voice communications in line with other information technologies.
APPENDIX A Understanding Telephony Utility is when you have one telephone, luxury is when you have two, opulence is when you have three—and paradise is when you have none. —Doug Larson In this appendix, we are going to talk about some of the technologies of the traditional telephone network—especially those that people most commonly want to connect to Asterisk. (We’ll discuss Voice over IP in Appendix B.
limited bandwidth means that some sound quality will be lost (as anyone who’s had to listen to music on hold can attest to), especially in the higher frequencies. Parts of an Analog Telephone An analog phone is composed of five parts: the ringer, the dialpad, the hybrid (or network), and the hook switch and handset (both of which are considered parts of the hybrid). The ringer, the dialpad, and the hybrid can operate completely independently of one another.
Table A-1. DTMF digits a 1209 Hz 1336 Hz 1477 Hz 1633 Hz a 697 Hz 1 2 3 A 770 Hz 4 5 6 B 852 Hz 7 8 9 C 941 Hz * 0 # D Notice that this column contains letters that are not typically present as keys on a telephone dialpad. They are part of the DTMF standard nonetheless, and any proper telephone contains the electronics required to create them, even if it doesn’t contain the buttons themselves.
Tip and Ring In an analog telephone circuit, there are two wires. In North America, these wires are referred to as Tip and Ring.‡ This terminology comes from the days when telephone calls were connected by live operators sitting at cord boards. The plugs that they used had two contacts—one located at the tip of the plug and the other connected to the ring around the middle (Figure A-1). Figure A-1. Tip and Ring The Tip lead is the positive polarity wire.
Download from Wow! eBook end. Then, at the far end, use the transmitted information to generate a completely new audio signal that has the same characteristics as the original. The reproduction is so good that the human ear can’t tell the difference. The principal advantage of digital audio is that the sampled data can be mathematically checked for errors all along the route to its destination, ensuring that a perfect duplicate of the original arrives at the far end.
To digitally encode the wave, it must be sampled on a regular basis, and the amplitude of the wave at each moment in time must be measured. The process of slicing up a waveform into moments in time and measuring the energy at each moment is called quantization, or sampling. The samples will need to be taken frequently enough and will need to capture enough information to ensure that the far end can re-create a sufficiently similar waveform. To achieve a more accurate sample, more bits will be required.
Figure A-4. PCM encoded waveform Figure A-5. Plotted PCM signal From this information, the waveform can be reconstructed (see Figure A-6). Figure A-6. Delineated signal As you can see if you compare Figure A-2 with Figure A-6, this reconstruction of the waveform is not very accurate.
important point: the quality of the digitally encoded waveform is affected by the resolution and rate at which it is sampled. At too low a sampling rate, and with too low a sample resolution, the audio quality will not be acceptable. Increasing the sampling resolution and rate Let’s take another look at our original waveform, this time using 5 bits to define our quantization intervals (Figure A-7). Figure A-7.
Figure A-8. The same waveform at double the resolution Figure A-9.
From this information, the waveform shown in Figure A-10 can then be generated. As you can see, the resultant waveform is a far more accurate representation of the original. However, you can also see that there is still room for improvement. Note that 40 bits were required to encode the waveform at 4-bit resolution, while 156 bits were needed to send the same waveform using 5bit resolution (and also doubling the sampling rate).
telephone network will not carry frequencies below 300 Hz and above 4,000 Hz, a sampling frequency of 8,000 samples per second will be sufficient to reproduce any frequency within the bandwidth of an analog telephone. Keep that 8,000 samples per second in mind; we’re going to talk about it more later. Logarithmic companding So, we’ve gone over the basics of quantization, and we’ve discussed the fact that more quantization intervals (i.e.
Figure A-11.
Figure A-12.
Aliasing If you’ve ever watched the wheels on a wagon turn backward in an old Western movie, you’ve seen the effects of aliasing. The frame rate of the movie cannot keep up with the rotational frequency of the spokes, and a false rotation is perceived. In a digital audio system (which the modern PSTN arguably is), aliasing always occurs if frequencies that are greater than one-half the sampling rate are presented to the analog-to-digital (A/D) converter.
Even the ubiquitous analog circuit is sampled into a DS-0 as soon as possible. Sometimes this happens where your circuit terminates at the central office, and sometimes well before.§ T-carrier circuits The venerable T1 is one of the more recognized digital telephony terms. A T1 is a digital circuit consisting of 24 DS-0s multiplexed together into a 1.544-Mbps bit stream.‖ This bit stream is properly defined as a DS-1. Voice is encoded on a T1 using the μlaw companding algorithm.
SONET and OC circuits The Synchronous Optical Network (SONET) was developed out of a desire to take the T-carrier system to the next technological level: fiber optics. SONET is based on the bandwidth of a T3 (44.736 Mbps), with a slight overhead making it 51.84 Mbps. This is referred to as an OC-1 or STS-1. As Table A-3 shows, all higher-speed OC circuits are multiples of this base rate. Table A-3.
supported) has to be sent as part of the audio stream. CAS is commonly used on the T1 link in channel banks. ISDN The Integrated Services Digital Network (ISDN) has been around for more than 20 years. Because it separates the channels that carry the traffic (the bearer channels, or B-channels) from the channel that carries the signaling information (the D-channel), ISDN allows for the delivery of a much richer set of features than CAS.
uses a single DS-0 channel as a signaling link (the D-channel); the remaining channels serve as B-channels. In North America, Primary Rate ISDN is commonly carried on one or more T1 circuits. Since a T1 has 24 channels, a North American PRI circuit typically consists of 23 Bchannels and 1 D-channel. For this reason, PRI is often referred to as 23B+D.* In Europe, a 32-channel E1 circuit is used, so a Primary Rate ISDN circuit is referred to as 30B+D (the final channel is used for synchronization).
Packet-Switched Networks In the mid-1990s, network performance improved to the point where it became possible to send a stream of media information in real time across a network connection. Because the media stream is chopped up into segments, which are then wrapped in an addressing envelope, such connections are referred to as packet-based.
APPENDIX B Protocols for VoIP The Internet is a telephone system that’s gotten uppity. —Clifford Stoll The telecommunications industry spans over 100 years, and Asterisk integrates most— if not all—of the major technologies that it has made use of over the last century. To make the most out of Asterisk, you need not be a professional in all areas, but understanding the differences between the various codecs and protocols will give you a greater appreciation and understanding of the system as a whole.
• • • • • G.729A GSM iLBC Speex MP3 We will then conclude the appendix with a discussion of how voice traffic can be routed reliably, what causes echo and how to deal with it, and how Asterisk controls the authentication of inbound and outbound calls. The Need for VoIP Protocols The basic premise of VoIP is the packetization* of audio streams for transport over Internet Protocol-based networks. The challenges to accomplishing this relate to the manner in which humans communicate.
thousands of packages, and then deliver each package in whatever way possible to the far end. Clearly, some way of dealing with this is required. VoIP Protocols The mechanism for carrying a VoIP connection generally involves a series of signaling transactions between the endpoints (and gateways in between), culminating in two persistent media streams (one for each direction) that carry the actual conversation. There are several protocols in existence to handle this.
Future Since IAX was optimized for voice, it has received some criticism for not better supporting video—but in fact, IAX holds the potential to carry pretty much any media stream desired. Because it is an open protocol, future media types are certain to be incorporated as the community desires them. Security considerations IAX includes the ability to authenticate in three ways: plain text, MD5 hashing, and RSA key exchange.
know today and contained only a single request type: a call setup request. In March 1999, after 11 revisions, SIP RFC 2543 was born. At first, SIP was all but ignored, as H.323 was considered the protocol of choice for VoIP transport negotiation. However, as the buzz grew, SIP began to gain in popularity, and while there may be a lot of different factors that accelerated its growth, we’d like to think that a large part of its success is due to its freely available specification.
sell unless a migration path to SIP is offered. SIP is widely expected to deliver far more than VoIP capabilities, including the ability to transmit video, music, and any type of real-time multimedia. While its use as a ubiquitous general-purpose media transport mechanism seems doubtful, SIP is unarguably poised to deliver the majority of new voice applications for the next few years. Security considerations SIP uses a challenge/response system to authenticate users.
H.323 This International Telecommunication Union (ITU) protocol was originally designed to provide an IP transport mechanism for videoconferencing. It has become the standard in IP-based video-conferencing equipment, and it briefly enjoyed fame as a VoIP protocol as well. While there is much heated debate over whether SIP or H.323 (or IAX) will come to dominate the VoIP protocol world, in Asterisk, H.323 has largely been deprecated in favor of IAX and SIP. H.
Security considerations H.323 is a relatively secure protocol and does not require many security considerations beyond those that are common to any network communicating with the Internet. Since H.323 uses the RTP protocol for media communications, it does not natively support encrypted media paths. The use of a VPN or other encrypted tunnel between endpoints is the most common way of securely encapsulating communications.
MGCP is defined in RFC 3435.* It was designed to make the end devices (such as phones) as simple as possible, and have all the call logic and processing handled by media gateways and call agents. Unlike SIP, MGCP uses a centralized model. MGCP phones cannot directly call other MGCP phones; they must always go through some type of controller. Asterisk supports MGCP through the chan_mgcp.so module, and the endpoints are defined in the configuration file mgcp.conf.
We’ve all seen optical illusions; likewise, voice-compression algorithms take advantage of our tendency to interpret what we believe we should hear, rather than what we actually hear.‡ The purpose of the various encoding algorithms is to strike a balance between efficiency and quality.§ Originally, the term codec referred to a COder/DECoder: a device that converts between analog and digital. Now, the term seems to relate more to COmpression/ DECompression.
G.711 imposes minimal (almost zero) load on the CPU. G.726 This codec has been around for some time (it used to be G.721, which is now obsolete), and it is one of the original compressed codecs. It is also known as Adaptive Differential Pulse-Code Modulation (ADPCM), and it can run at several bitrates. The most common rates are 16 Kbps, 24 Kbps, and 32 Kbps. As of this writing, Asterisk supports only the ADPCM-32 rate, which is far and away the most popular rate for this codec. G.
than that produced by G.729A, but much of this comes down to personal opinion; be sure to try it out. GSM operates at 13 Kbps. iLBC The Internet Low Bitrate Codec (iLBC) provides an attractive mix of low bandwidth usage and quality, and it is especially well suited to sustaining reasonable quality on lossy network links.
MP3 Sure thing, MP3 is a codec. Specifically, it’s the Moving Picture Experts Group Audio Layer 3 Encoding Standard.# With a name like that, it’s no wonder we call it MP3! In Asterisk, the MP3 codec is typically used for music on hold (MoH). MP3 is not a telephony codec, as it is optimized for music, not voice; nevertheless, it’s very popular with VoIP telephony systems as a method of delivering MoH. Be aware that music cannot usually be broadcast without a license.
The purpose of TCP is to guarantee the delivery of packets. In order to do this, several mechanisms are implemented, such as packet numbering (for reconstructing blocks of data), delivery acknowledgment, and re-requesting of lost packets. In the world of VoIP, getting the packets to the endpoint quickly is paramount—but 20 years of cellular telephony has trained us to tolerate a few lost packets.
By addressing the major shortcomings of TCP and UDP, SCTP’s developers hoped to create a robust protocol for the transmission of SS7 and other types of PSTN signaling over an IP-based network. Differentiated Service Differentiated service, or DiffServ, is not so much a QoS mechanism as a method by which traffic can be flagged and given specific treatment. Obviously, DiffServ can help to provide QoS by allowing certain types of packets to take precedence over others.
dynamic by distributing control of labels to the routers. This enables the network to become more responsive to changing conditions, because it can be set up to change the paths based on certain conditions, such as a certain path going down (perhaps due to a faulty router). The configuration within the router will then be able to use RSVP to distribute new labels to the routers in the MPLS network, with no (or minimal) human intervention.
If you hear echo, it’s not your phone that’s causing the problem; it’s the far end of the circuit. Conversely, echo heard on the far end is being generated at your end. Echo can be caused by the fact that an analog local loop circuit has to transmit and receive on the same pair of wires. If this circuit is not electrically balanced, or if a low-quality telephone is connected to the end of the circuit, signals it receives can be reflected back, becoming part of the return transmission.
Asterisk and VoIP It should come as no surprise that Asterisk loves to talk VoIP. But in order to do so, Asterisk needs to know which function it is to perform: that of client, server, or both. One of the most complex and often confusing concepts in Asterisk is the configuration of inbound and outbound authentication. Users and Peers and Friends—Oh My! Connections that authenticate to us, or that we authenticate, are defined in the iax.conf and sip.conf files as users and peers.
it. If the remote end is another Asterisk box, the use of a register statement is required, as discussed in the next section. Friends Defining a type as a friend is a shortcut for defining it as both a user and a peer. However, connections that are both users and peers aren’t always defined this way, because defining each direction of call creation individually (using both a user and a peer definition) allows more granularity and control over the individual connections.
Download from Wow! eBook Your service provider will have a definition in either its sip.conf or iax.conf configuration file (depending on whether you are connecting with the SIP or IAX protocol, respectively) for your Asterisk server. If you only receive calls from this provider, you will define it as a user (if it is another Asterisk system, you might be defined in its system as a peer). Now let’s say that your box is on your home Internet connection, with a dynamic IP address.
Encrypting Audio with Secure RTP If you can sniff the packets coming out of an Asterisk system, you can extract the audio from the RTP streams. This data can be fed offline to a speech processing system, which can listen for keywords such as “credit card number” or “PIN” and present the data it gathers to someone who has an interest in it.
DMZ. Placing your VoIP system in a demilitarized zone (DMZ) can provide an additional layer of protection for your LAN, while still allowing connectivity for relevant applications. Should your VoIP system be compromised, it will be much more difficult to use it to launch an attack on the rest of your network, since it is not trusted. Regardless of whether you deploy within a DMZ, any abnormal traffic coming out of the system should be considered suspect. Server hardening.
APPENDIX C Preparing a System for Asterisk Very early on, I knew that someday in some “perfect” future out there over the horizon, it would be commonplace for computers to handle all of the necessary processing functionality internally, making the necessary external hardware to connect up to telecom interfaces very inexpensive and, in some cases, trivial.
although the underlying causes will be different. As loads increase, the system will have increasing difficulty maintaining connections. For a PBX, such a situation is nothing short of disastrous, so careful attention to performance requirements is a critical consideration during the platform selection process. Table C-1 lists some very basic guidelines that you’ll want to keep in mind when planning your system.
If you are sure that you need to set up a distributed Asterisk system, you will want to study the DUNDi protocol, the Asterisk Realtime Architecture (ARA), func_odbc, and the various other database tools at your disposal. This will help you to abstract the data your system requires from the dialplan logic your Asterisk systems will utilize, creating a generic set of dialplan logic that can be used across multiple boxes.
Whether conferencing will be provided, and what level of conferencing activity is expected Will the system be used heavily? Conferencing requires the system to transcode and mix each individual incoming audio stream into multiple outgoing streams. Mixing multiple audio streams in near-real time can place a significant load on the CPU. Echo cancellation Echo cancellation may be required on any call where a Public Switched Telephone Network (PSTN) interface is involved.
support. The next section (“Choosing a Processor” on page 644) offers some general guidelines for choosing a CPU that will meet the needs of your system. Other processes running concurrently on the system Being Unix-like, Linux is designed to be able to multitask several different processes. A problem arises when one of those processes (such as Asterisk) demands a very high level of responsiveness from the system. By default, Linux will distribute resources fairly among every application that requests them.
Linux has historically had problems with its ability to service IRQs quickly; this problem has caused enough trouble for audio developers that several patches have been created to address this shortcoming. So far, there has been some mild controversy over how to incorporate these patches into the Linux kernel. Kernel version Asterisk is officially supported on Linux version 2.6. Almost all of Asterisk itself does not really care about the kernel version, but DAHDI requires 2.6.
To attempt to provide you with a frame of reference from which you can contemplate your platform decision, we have chosen to define three sizes of Asterisk systems: small, medium, and large. Small systems Small systems (up to 10 phones) are not immune to the performance requirements of Asterisk, but the typical load that will be placed on a smaller system will generally fall within the capabilities of a modern processor.
stressed. Users may begin to perceive quality problems without realizing that the system is not faulty in any way, but simply exceeding its capacity. These problems will get progressively worse as more and more load is placed on the system, with the user experience degrading accordingly. It is critical that performance problems be identified and addressed before users notice them.
however, as APIC-enabled motherboards turn IRQ control over to the operating system. • Server-class motherboards generally implement a different PCI standard than workstation-class motherboards. While there are many differences, the most obvious and well known is that the two versions have different voltages. Depending on which cards you purchase, you will need to know if you require 3.3V or 5V PCI slots.‖ Figure C-1 shows the visual differences between 3.3V and 5V slots.
• If you need a modem, install an external unit that connects to a serial port. If you must have an internal modem, you will need to ensure that it is not a so-called “Win-modem”—it must be a completely self-sufficient unit (note that these are very difficult, if not impossible, to find). • Consider that with built-in networking, if you have a network component failure, the entire motherboard will need to be replaced.
This oft-neglected component can turn an otherwise top-quality system into a poor performer. By the same token, a top-notch power supply might enable an otherwise cheap PC to perform like a champ. The power supplied to a system must provide not only the energy a system needs to perform its tasks but also stable, clean signal lines for all of the voltages the system expects from it.
One of the benefits of clean power is a reduction in heat, which means less stress on components, leading to a longer life expectancy. Properly grounded, conditioned power feeding a premium-quality power supply will ensure a clean logic ground (a.k.a. 0-volt) reference‡ for the system and keep electrical noise on the motherboard to a minimum. These are industry-standard best practices for this type of equipment, which should not be neglected.
One of the authors recalls once frying a sound card he was trying to connect to a friend’s stereo system.
It is also vital that each and every peripheral you connect to your system be connected to the same electrical receptacle (or, more specifically, the same ground reference). This will cut down on the occurrence of ground loops, which can cause anything from buzzing and humming noises to damaged or destroyed equipment. Electrical Circuits If you’ve ever seen the lights dim when an electrical appliance kicks in, you’ve seen the effect that a high-energy device can have on an electrical circuit.
Temperature Heat is the enemy of electronics. The cooler you keep your system, the more reliably it will perform, and the longer it will last. If you cannot provide a properly cooled room for your system, at a minimum ensure that it is placed in a location that ensures a steady supply of clean, cool air. Also, keep the temperature steady. Changes in temperature can lead to condensation and other damaging changes.
Because of Asterisk’s open architecture (and open source code), it is ultimately possible to connect any standards-compliant interface hardware. The selection of open source telephony interface boards is currently limited, but as interest in Asterisk grows, that will rapidly change.† At the moment, one of the most popular and cost-effective ways to connect to the PSTN is to use the interface cards that evolved from the work of the Zapata Telephony Project (http://www.zapatatelephony.
The Zapata Telephony Project originally produced a T1 card, the Tormenta, that is the ancestor of most Asterisk-compatible T1 cards. The original Tormenta cards are now considered obsolete, but they do still work with Asterisk. Digium makes several different digital circuit interface cards. The features on the cards are the same; the primary differences are whether they provide T1 or E1 interfaces, and how many spans each card provides.
eBay. Look for units from Adtran and Carrier Access Corp. (Rhino makes great channel banks, and they are very competitively priced, but they may be hard to find used.) Don’t forget that you will need a T1 card in order to connect a channel bank to Asterisk. Other types of PSTN interfaces Many VoIP gateways exist that can be configured to provide access to PSTN circuits. Generally speaking, these will be of most use in a smaller system (one or two lines).
of suffering later. Echo problems are not pleasant at all, and your users will hate the system if they experience it. Several software echo cancellers have recently become available. We have not had a chance to evaluate any of them, but we know that they employ the same algorithms the hardware echo cancellers do. If you have a recently purchased Digium analog card, you can call Digium sales for a keycode to allow its latest software echo canceller to work with your system.
This section takes a brief look at the various user (or endpoint) devices you might want to connect to your Asterisk system. We delve more deeply into the mechanics of analog and digital telephony in Appendix A. Analog telephones Analog phones have been around since the invention of the telephone. Up until about 20 years ago, all telephones were analog. Although analog phones have some technical differences in different countries, they all operate on similar principles.
The chances of anyone ever making a proprietary digital phone directly compatible with Asterisk are slim, but companies such as Citel (http://www.citel.com)§ have created gateways that convert the proprietary signals to Session Initiation Protocol (SIP).‖ ISDN telephones Prior to VoIP, the closest thing to a standards-based digital telephone was an ISDNBRI terminal.
IP telephones IP telephones are heralds of the most exciting change in the telecommunications industry. Already, standards-based IP telephones are available in retail stores. The wealth of possibilities inherent in these devices will cause an explosion of interesting applications, from video phones to high-fidelity broadcasting devices to wireless mobility solutions to purpose-built sets for particular industries to flexible all-in-one multimedia systems.
Download from Wow! eBook Having thus muddied the waters, the best we can do at this point is to define what the term softphone will refer to in relation to this book, with the understanding that the meaning of the term can be expected to undergo a massive change over the next few years.
• If I use my PDA to connect to my voicemail and retrieve my voice messages (converted to text), does my PDA become a phone? • If I attach a video camera to my PC, connect to a company’s website, and request a live chat with a customer service rep, is my PC now a telephone? • If I use the IP phone in my kitchen to surf for recipes, is that a phone call? The point is simply this: we’ll probably always be “phoning” each other, but will we always use “telephones” to do so? Linux Considerations If you ask anyo
Index Symbols ! (exclamation mark), in section name, 92 # (hash symbol) comment, 188 delimiter between map names, 226 $[] (dollar sign square brackets) Asterisk expressions, 195 ${DIALSTATUS} variable, 170 ${eventextra} CEL variable, 544 ${eventtime} CEL variable, 544 ${eventtype} CEL variable, 544 ${EXTEN} channel variable, 128, 240 ${IPADDR} option (dundi.conf), 506 ${NUMBER} option (dundi.conf), 506 ${SECRET} option (dundi.
statistics: queue_log file, 296–299 ackcall option (agents.conf), 281 ACLs (access control lists), 574 actions, AMI message encoding, 467 adaptors, VoIP paging adaptors, 234 ADDMEMBER event, 298 addon modules, 23 AddQueueMember() application, 268, 285, 295 Adhearsion, 488 adsifdn option (voicemail.conf), 160 adsipark (features.conf), 223 adsisec option (voicemail.conf), 160 adsiver option (voicemail.conf), 160 agent option (agents.conf), 282 agent option (manager.
announce-position option (queues.conf), 278, 288 announce-position-limit option (queues.conf), 278, 288 announce-round-seconds option (queues.conf), 278, 288 announcement control, 287–291 ANSWER AGI command, 483 answer CDR field, 528 ANSWER CEL event type, 537 Answer() application, 113 anti-monopolistic practices, 593 aoc option (manager.
astctlowner (asterisk.conf), 75 astctlpermissions (asterisk.conf), 75 astdatadir (asterisk.conf), 72 AstDB (Asterisk Database), 214–216 deleting data from, 215 retrieving data from, 214 storing data in, 214 using in the dialplan, 215 astdbdir (asterisk.
autokill option (dundi.conf), 506 autokill option (sip.conf), 96 autoload (modules.conf), 77 autologoff option (agents.conf), 281 autologoffunavail option (agents.conf), 281 automixmon (features.conf), 225 automon (features.conf), 225 autopause option (queues.conf), 276 autoprune option (jabber.conf), 420 autoregister option (jabber.conf), 420 autosystemname (asterisk.
controlling calls based on calendar information, 407 triggering calendar reminders, 402–406 writing call information to a calendar, 408– 411 CALENDAR_BUSY() dialplan function, 407, 411 CALENDAR_EVENT() dialplan function, 403 CALENDAR_QUERY() function, 411 CALENDAR_QUERY_RESULT() function, 411 call centers, 489 call centers, inbound and outbound, 261 call detail records (see CDRs) call information, writing to a calendar, 408– 411 call monitoring for law enforcement agencies, 593 call option (manager.
two-party call, 547 cel.
cidinternalcontexts option (voicemail.conf), 163 cidname, 539 cidnum CEL event field, 539 cidrdnis CEL event field, 539 circuit types, 610 Cisco SPA phones: multicast paging, 234 SIP-based paging, 232 Class (SIP SRV record), 239 CLI (command-line interface), controlling queue members, 266 clid CDR field, 527 closetimeout option (voicemail.
lsdahdi command, 142 make menuselect command, 50, 352 manager show command, 467 manager show command AGI command, 485 manager show commands, 467 md5sum command, 435 menuselect command, 76 module reload app_queue.
IAX trunks, 153 iax.conf, 95–98, 514, 515, 573 indications.conf, 77 initial configuration, 52–59 IP phones, 184 jail.conf, 570 LDAP support, 437 loading new channel configurations, 98 make menuselect, 59–64 about, 59 interfaces, 60 scripting, 63 using, 61 manager.conf, 460–464 modules.conf, 56, 75 musiconhold.conf, 79 MySQL, 345 ODBC for Microsoft SQL, 350 ODBC for MySQL, 349 ODBC for PostgreSQL, 347 OpenAIS, 311 OpenLDAP, 435 OpenNMS, 552–558 PostgreSQL, 343 PRI circuits, 138 queuerules.conf, 285 res_ldap.
cURL module, installing, 393 CURL() dialplan function, 392, 394 Custom: virtual device, 301 custom_beep option (agents.
external to the Asterisk server, 182–185 state information, 295 testing device registration, 99 DEVICE_STATE() dialplan function, 302 dial by extension, 336 Dial() application, 119–122, 207, 211, 434 dial-by-name directories, 171 dialing SIP URIs from Asterisk, 246 dialout option (voicemail.
DIDs (direct inward dialing numbers), 145 differentiated service, 631 digit 9, accessing external lines, 132 digital circuit-switched telephone network, 610–614 digital circuits, configuring, 138 digital interface cards, requirements, 654 digital signaling protocols, 612 digital telephones, requirements, 658 digital telephony about, 600–610 PSTN circuits, 135 digitally encoding an analog waveform, 601 Digium cards, 100, 136, 185–189, 186 FAA, 446 packages, 46 Digium Asterisk Hardware Device Interface (see D
echo on DAHDi channels, 633 dundi lookup command, 513 dundi show peer command, 513 dundi.conf, 505 DUNDILOOKUP() function, 519 DUNDIQUERY() function, 519, 520 DUNDIRESULT() function, 519, 520 duration CDR field, 528 dust requirements, 653 dynamic realtime, 176, 368, 371–375 dynamically adding extension numbers, 517 DYNAMIC_FEATURES variable, 226, 227 E E.164, 590 e164.org, 591 EAGI (Enhanced AGI), 477 eastern option (voicemail.
extension numbers, DUNDi and Asterisk configuration, 517 extension states, 303–305 extensions about, 84 adding special extensions, 119 dialplan syntax, 110 traditional phone systems, 363 extensions.
resource library, 25 spool, 25 FILTER() function, 242 FilteredExtension channel variable, 242 findslot (features.conf), 223 findslot directive, 228 Flash Operator Panel (FOP), 473, 562 floating point unit, 642 FOP (Flash Operator Panel), 473, 562 forcegreetings option (voicemail.conf), 165 forcename option (voicemail.conf), 164 format interpreters, 18 music, 79 outgoing fax handling, 450 format option (voicemail.
g(#) (VoiceMailMain() application), 171 G.711 codec, 626 G.722 codec, 626, 628 G.726 codec, 626, 627 G.729A codec, 626, 627 [general] section agents.conf, 281 cdr.conf, 529 cel.conf, 540 Comedian Mail, 158–166 context, 109 dundi.conf, 505 features.conf, 222–224 http.conf, 464 jabber.conf, 420 manager.conf, 460 queues.conf, 275 sip.conf, 374 sla.
ignoreip option (jail.conf), 570 ignoreregexpire option (sip.conf), 374 iLBC (Internet Low Bitrate Codec) about, 628 quick reference, 626 IMAP (Internet Message Access Protocol) enabling on your Gmail account, 415 library: compiling voicemail support, 413 voicemail integration, 411–418 IMAP (Internet message application protocol) voicemail storage backends, 173 imapflags option (voicemail.conf), 416 imapfolder option (voicemail.conf), 417 imapgreetings option (voicemail.
ISNs, 254 security and identity, 256–259 distributed denial of service attacks, 258 phishing, 258 security as an ongoing process, 259 SPIT, 258 toll fraud, 257 Internet Low Bitrate Codec (see iLBC) Internet message application protocol (see IMAP) interpreters, format interpreters, 18 invalid handler, AA, 335 IP multicast about, 233 support for, 233 IP telephones about, 183 requirements, 660 iptables, 568 IPv6 localhost, PostgreSQL, 344 IPv6, sip.
spandsp, 444 LibSRTP, 150 licensing, music on hold, 79 lightbackground (asterisk.conf), 74 Lightweight Directory Access Protocol (see LDAP) limit option (res_odbc.conf), 352 linkedid CEL event field, 539 LINKEDID_END CEL event type, 537 Linksys Key System Parameters (SPA phones), 234 Linksys phones, SIP-based paging, 232 Linux distributions, 644 filesystem: storage backends, 172 ODBC, 346 requirements, 662 syslog daemon, 526 listen-control-forward-key option (voicemail.
Download from Wow! eBook membermacro option (queues.conf), 278 members penalizing, 284 menuselect, 59–64 about, 59 interfaces, 60 scripting, 63 using, 61 menuselect command, 76 menuselect system, 59 menuselect.makeopts, 64 message encoding, AMI, 466 messages, voice messages, 172 messagewrap option (voicemail.
Network Time Protocol (see NTP) networks digital circuit-switched telephone network, 610–614 packet-switched networks, 615 nextaftercmd option (voicemail.conf), 164 nocallerid (Zapateller() application), 217 nocolor (asterisk.conf), 73 nocomunsolicit option (dundi.conf), 506 nofork (asterisk.conf), 72 noinclude option (dundi.conf), 507 noload (modules.conf), 77 noload directive, 76 NOOP AGI command, 483 NoOp() dialplan application, 516 nopartial option (dundi.
P P (VoiceMail() application), 170 p (VoiceMailMain() application), 171 packages, Asterisk packages, 30 packet-switched networks about, 615 hardware requirements, 656 Page() application, 231, 235 Page() command, 234 PAGELIST variable, 235 pagerbody option (voicemail.conf), 161 pagerdateformat option (voicemail.conf), 161 pagerfromstring option (voicemail.conf), 161 pagersubject option (voicemail.
persistentmembers option (queues.conf), 275 phishing, 258 phone option (dundi.conf), 505 phones naming, 85 requirements, 657–662 security, 586 PHPAGI, 488 physical security, 638 pickupexten (features.conf), 223 pickupfailsound (features.conf), 223 pickupsound (features.conf), 223 pipe character (|) delimiter, 167 support for, 113 voicemail.conf, 417 Playback() application, 114, 337 playback, prompts within a queue, 288 pollfreq option (voicemail.conf), 162, 416 pollmailboxes option (voicemail.
Queue() application, 291, 294, 499 queue-callswaiting option (queues.conf), 279, 289 queue-holdtime option (queues.conf), 279, 289 queue-minutes option (queues.conf), 279, 289 queue-reporthold option (queues.conf), 279, 289 queue-seconds option (queues.conf), 279, 289 queue-thankyou option (queues.conf), 278, 288 queue-thereare option (queues.conf), 278, 289 queue-youarenext option (queues.conf), 278, 289 queuerules.
require (modules.conf), 77 requirements, 639–662 environment, 649–653 hardware, 26 Linux, 662 phones, 657–662 servers, 641–649 telephony hardware, 653–657 residential option (dundi.conf), 506 resource library, 25 resource modules, 21 res_agi (asterisk.conf), 75 res_calendar_ews module, 399 res_config_mysql addon module, 23 res_ldap.conf, 437 res_odbc configuring to allow Asterisk to connect through ODBC, 352 res_odbc.conf, 382 res_snmp, 551 res_snmp.conf, 553 retry option (queues.
phishing, 258 PSTN circuits and VoIP connections, 145 scanning for valid accounts, 565 servers, 653 SIP, 622 SPIT, 258 test users, 383 toll fraud, 257 VoIP, 636–638 DMZ, 638 encryption, 637, 638 physical security, 638 segregating voice and data traffic, 637 server hardening, 638 SPIT, 636 spoofing, 637 segregating voice and data traffic, 637 SELinux (Security-Enhanced Linux), 51 SEND IMAGE AGI command, 484 SEND TEXT AGI command, 484 SendFAX() dialplan application, 450 sending email, 568 sendvoicemail option
configuring chan_skype.
storing data in, 214 using in the dialplan, 215 backends, 172–173 IMAP, 173 Linux filesystem, 172 ODBC, 173 storehistory option (dundi.conf), 506 strategy option (queues.conf), 264, 275 STREAM FILE AGI command, 484 strong passwords, 567 studio prompts, 337 stunaddr option (gtalk.conf), 426 subFreenum context, 255 subroutines, GoSub() dialplan application, 207–211 subscribecontext option (sip.
toll fraud, 591 unified messaging, 590 video, 588 VoIP spam, 592 wireless, 589 Asterisk community, 5–8 Asterisk Documentation Project, 8 IRC channels, 7 mailing lists, 6 user groups, 7 wiki sites, 7 Asterisk: the hacker’s PBX, 4 Asterisk: the professional’s PBX, 5 business case, 8 change and flexibility, 3 open source telephony, 580–586 community, 582 conference rooms, 585 consumers needs, 580 home automation, 586 legacy PBX migration gateway, 582 low-barrier IVR, 583 open architecture, 581 response to new
about, 257 future of telephony, 591 NANP and toll fraud, 127 toll lines, accessing, 133 tones, changing, 194 tos option (dundi.conf), 505 transcode_via_sln (asterisk.conf), 74 transcoding codecs, 642 performance, 18 TRANSFER event, 299, 538 transferdigittimeout (features.conf), 223 translation cost, audio formats, 114 translators, codec translators, 18 Transmission Control Protocol (see TCP) transmit_silence (asterisk.
authentication, 634 chan_skype.conf, 430 users.conf, 84 userscontext option (voicemail.conf), 160 USER_DEFINED CEL event type, 538 usesasl option (jabber.conf), 420 usetls option (jabber.conf), 420 V validating ODBC connector, 351 passwords, 162 variable argument (Read() application), 390 variables, 122–125 adding to dialplan, 124 channel variables, 123 environment variables, 124 global variables, 123 verbose (asterisk.conf), 72 VERBOSE AGI command, 484 verbose logger.
SPIT, 636 spoofing, 637 SIP, 620–622 spam, 592 telephony future, 2 UNISTIM, 625 VoIP to VoIP, 147 volgain option (voicemail.conf), 164 W WAIT FOR DIGIT AGI command, 484 WaitExten() application, 117 wakeup calls, 402 WAN (wide area network), distributed device states, 497 warning logger.
About the Authors Leif Madsen first got involved with the Asterisk community when he was looking for a voice conferencing solution. Once he learned that there was no official Asterisk documentation, he co-founded the Asterisk Documentation Project. Leif is currently working as a consultant, specializing in Asterisk clustering and call-center integration. You can find out more about him at http://www.leifmadsen.com. Jim Van Meggelen is a founding partner and CTO of Core Telecom Innovations, Inc.
Download from Wow! eBook