Asterisk Admin Guide

Asterisk-Admin-Guide

Asterisk-Admin-Guide

Asterisk-Admin-Guide

Asterisk-Admin-Guide

Asterisk-Admin-Guide

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 679

DownloadAsterisk-Admin-Guide
Open PDF In BrowserView PDF
Asterisk Administrator Guide
Asterisk Development Team 

1. Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1 Precursors, Background and Business . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.1.1 Asterisk Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2 Beginning Asterisk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.1 Installing Asterisk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2.2 Asterisk Configuration Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.2.3 Basic PBX Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
1.2.4 Dialplan Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
1.2.5 Auto-attendant and IVR Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
1.2.6 Dialplan Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
1.2.7 Installing Asterisk From Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
1.2.8 Getting Started with Asterisk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
1.2.9 Asterisk Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
1.2.10 Asterisk on (Open)Solaris . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
2. Configuration and Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
2.1 Asterisk Calendaring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
2.1.1 Configuring Asterisk Calendaring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
2.1.2 Calendaring Dialplan Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
2.1.3 Calendaring Dialplan Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
2.2 Asterisk Channel Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
2.2.1 Inter-Asterisk eXchange protocol, version 2 (IAX2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
2.2.2 mISDN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
2.2.3 Local Channel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
2.2.4 Mobile Channel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
2.2.5 Unistim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
2.2.6 Skinny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
2.3 Asterisk Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
2.3.1 General Configuration Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
2.3.2 Database Support Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
2.3.3 Privacy Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
2.4 Asterisk Extension Language (AEL) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
2.4.1 Introduction to AEL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
2.4.2 AEL and Asterisk in a Nutshell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
2.4.3 Getting Started with AEL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
2.4.4 AEL Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
2.4.5 About "aelparse" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
2.4.6 General Notes about AEL Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
2.4.7 AEL Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
2.4.8 AEL Procedural Interface and Internals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
2.4.9 AEL Example Usages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
2.4.10 AEL Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
2.4.11 AEL Semantic Checks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
2.4.12 Differences with the original version of AEL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
2.4.13 AEL Hints and Bugs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
2.4.14 The Full Power of AEL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
2.5 Asterisk Manager Interface (AMI) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
2.5.1 The Asterisk Manager TCP IP API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
2.5.2 AMI Command Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
2.5.3 AMI Manager Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
2.5.4 AMI Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
2.5.5 Ensuring all modules are loaded with AMI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
2.5.6 Device Status Reports with AMI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
2.5.7 Some Standard AMI Headers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
2.5.8 Asynchronous Javascript Asterisk Manger (AJAM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
2.6 Asterisk Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
2.6.1 Configuring Call Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
2.6.2 Queue Logs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
2.7 Asterisk Security Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
2.7.1 Security Framework Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
2.7.2 Security Event Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
2.7.3 Asterisk Security Event Logger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303

2.7.4 Security Events to Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.7.5 Security Log File Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.8 Asterisk Sounds Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.8.1 Getting the Sounds Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.8.2 About the Sounds Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9 Call Completion Supplementary Services (CCSS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9.1 CCSS Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9.2 The Call Completion Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9.3 Call Completion Info and Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9.4 Generic Call Completion Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10 Call Detail Records (CDR) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.1 CDR Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.2 CDR Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.3 CDR Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.4 CDR Storage Backends . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.11 Calling using Google . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12 Channel Event Logging (CEL) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.1 CEL Design Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.2 CEL Events and Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.3 CEL Applications and Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.4 CEL Configuration Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.5 Generating Billing Information from CEL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.6 CEL Storage Backends . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13 Channel Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.1 Parameter Quoting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.2 About Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.3 Variable Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.4 Selecting Characters from Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.5 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.6 Asterisk Standard Channel Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.7 Case Sensitivity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.14 Distributed Universal Number Discovery (DUNDi) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.14.1 Introduction to DUNDi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.14.2 DUNDIQUERY and DUNDIRESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.14.3 DUNDi Peering Agreement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.15 E.164 NUmber Mapping (ENUM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.15.1 The ENUMLOOKUP Dialplan Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.1 Asterisk Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.2 Asterisk Call Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.3 Asterisk Command Line Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.4 Asterisk Manager Interface (AMI) Changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.5 Building Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.6 Call Completion Supplementary Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.7 Call Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.8 Channel Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.9 Corosync . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.10 Database Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.11 Distributed Device State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.12 DUNDi - Distributed Universal Number Discovery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.13 External IVR Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.14 Followme - Realtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.15 IAX2 Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.16 LDAP Realtime Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.17 Open Settlement Protocol (OSP) User Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.18 PSTN Connectivity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.19 Real-time Text (T.140) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.20 RTP Packetization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.21 Simple Message Desk Interface (SMDI) Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.22 Simple Network Management Protocol (SNMP) Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.23 SIP Retransmissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

304
305
307
308
309
310
311
312
314
316
317
318
319
320
321
332
336
337
347
349
352
353
354
364
365
366
367
369
370
384
400
402
403
404
405
410
411
419
420
425
427
428
437
452
453
454
455
458
459
472
480
483
484
490
492
509
517
518
520
523
535

2.16.24 SIP TLS Transport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.25 Speech Recognition API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.26 SQLite Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.27 Storing Voicemail in PostgreSQL via ODBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.28 Timing Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.29 Using the Hoard Memory Allocator with Asterisk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.30 Video Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.31 Video Telephony . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17 Lua Dialplan Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.1 Dialplan to Lua Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.2 Interacting with Asterisk from Lua (apps, variables, and functions) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.3 Lua Dialplan Tips and Tricks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.4 Lua Dialplan Hints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.5 Lua Dialplan Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.6 Advanced pbx_lua Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.18 Manipulating Party ID Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.19 Packet Loss Concealment (PLC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.19.1 PLC Background on Translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.19.2 PLC Restrictions and Caveats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.19.3 Requirements for PLC Use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.19.4 PLC Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.20 Phone Provisioning in Asterisk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.20.1 Configuration of phoneprov.conf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.20.2 Creating Phone Profiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.20.3 Configuration of users.conf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.20.4 Phone Provisioning Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.20.5 Phone Provisioning, Putting it all together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.21 Reference Information Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.21.1 License Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.21.2 Important Security Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.21.3 Telephony Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.22 Secure Calling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.22.1 Secure Calling Specifics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.22.2 Secure Calling Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.23 Shared Line Appearances (SLA) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.23.1 Introduction to Shared Line Appearances (SLA) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.23.2 SLA Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.23.3 SLA Configuration Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.23.4 SLA and Call Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.24 Short Message Service (SMS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.24.1 Introduction to SMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.24.2 SMS and extensions.conf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.24.3 SMS Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.24.4 SMS Delivery Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.24.5 SMS File Formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.24.6 SMS Sub Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.24.7 SMS Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.24.8 SMS Typical Use with Asterisk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.24.9 Using SMSq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.25 Voicemail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.25.1 ODBC Voicemail Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.25.2 IMAP Voicemail Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.26 Asterisk SIP Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.27 Asterisk GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.28 Historical Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.28.1 Jabber in Asterisk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.28.2 Old Calling using Google . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3. Asterisk Versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4. Asterisk Module Support States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5. Asterisk Issue Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6. Asterisk Community . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

537
539
544
547
554
556
557
560
561
562
567
569
571
572
574
576
581
582
583
584
585
586
587
588
589
590
591
592
593
595
600
605
606
607
613
614
615
620
624
629
630
631
632
633
634
635
636
637
638
640
641
642
650
651
655
656
658
662
664
669
675

6.1 Asterisk Community Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2 Community Services Signup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3 IRC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.4 Mailing Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

676
677
678
679

Getting Started
A Beginners Guide to Asterisk. Herein, you will find content related to installing Asterisk and basic usage concepts.

Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License.

6

Precursors, Background and Business
Discovering Asterisk
This section of the documentation attempts to explain at a high level what Asterisk is and does. It also attempts to provide primers on the key technical
disciplines that are required to successfully create and manage Asterisk solutions. Much of the material in this section is optional and may be redundant for
those with a background in communications application development. For the other 99.9875% of the population, this is good stuff. Read on...

Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License.

7

Asterisk Concepts
Asterisk is a very large application that does many things. It can be somewhat difficult to understand, especially if you are new to communications
technologies. In the next few chapters we will do our best to explain what Asterisk is, what it is not, and how it came to be this way. This section doesn't
cover the technology so much as the concept. If you're already familiar with the function of a telephony engine, feel free to jump ahead to the next section.

Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License.

8

Asterisk as a Swiss Army Knife of Telephony
What Is Asterisk?
People often tend to think of Asterisk as an "open source PBX" because that was the focus of the original development effort. But calling Asterisk a PBX is
both selling it short (it is much more) and overstating it (it can be much less). It is true that Asterisk started out as a phone system for a small business (see
the "Brief History" section for the juicy details) but in the decade since it was originally released it has grown into a universal tool for building
communications applications. Today Asterisk powers not only IP PBX systems but also VoIP gateways, call center systems, conference bridges, voicemail
servers and all kinds of other applications that involve real-time communications.
Asterisk is not a PBX but is the engine that powers PBXs. Asterisk is not an IVR but is the engine that powers IVRs. Asterisk is not a call center ACD but
is the engine that powers ACD/queueing systems.
Asterisk is to communications applications what the Apache web server is to web applications. Apache is a web server. Asterisk is a communication
server. Apache handles all the low-level details of sending and receiving data using the HTTP protocol. Asterisk handles all the low level details of sending
and receiving data using lots of different communication protocols. When you install Apache, you have a web server but its up to you to create the web
applications. When you install Asterisk, you have a communications server but its up to you to create the communications applications.
Web applications are built out of HTML pages, CSS style sheets, server-side processing scripts, images, databases, web services, etc. Asterisk
communications applications are built out Dialplan scripts, configuration files, audio recordings, databases, web services, etc. For a web application to
work, you need the web server connected to the Internet. For a communications application to work, you need the communications server connected to
communication services (VoIP or PSTN). For people to be able to access your web site you need to register a domain name and set up DNS entries that
point "www.yourdomain.com" to your server. For people to access your communications system you need phone numbers or VoIP URIs that send calls to
your server.
In both cases the server is the plumbing that makes your application work. The server handles the low-level complexities and allows you, the application
developer, to concentrate on the application logic and presentation. You don't have to be an expert on HTTP to create powerful web applications, and you
don't have to be an expert on SIP or Q.931 to create powerful communications applications.
Here's a simple example. The following HTML script, installed on a working web server, prints "Hello World" in large type:



Hello World Demo


Hello World!

The following Dialplan script answers the phone, waits for one second, plays back "hello world" then hangs up. exten exten exten exten => => => => 100,1,Answer() 100,n,Wait(1) 100,n,Playback(hello-world) 100,n,Hangup() In both cases the server components are handling all of the low level details of the underlying protocols. Your application doesn't have to worry about the byte alignment, the packet size, the codec or any of the thousands of other critical details that make the application work. This is the power of an engine. Who Uses Asterisk? Asterisk is created by communication system developers, for communication system developers. As an open source project, Asterisk is a collaboration between many different individuals and companies, all of which need a flexible communications engine to power their applications. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 9 A Brief History of the Asterisk Project Way, way back in 1999 a young man named Mark Spencer was finishing his Computer Engineering degree at Auburn University when he hit on an interesting business concept. 1999 was the high point in the .com revolution (aka bubble), and thousands of businesses world-wide were discovering that they could save money by using the open source Linux operating system in place of proprietary operating systems. The lure of a free operating system with open access to the source code was too much to pass up. Unfortunately there was little in the way of commercial support available for Linux at that time. Mark decided to fill this gap by creating a company called "Linux Support Services". LSS offered a support hotline that IT professionals could (for a fee) call to get help with Linux. The idea took off. Within a few months, Mark had a small office staffed with Linux experts. Within a few more months the growth of the business expanded demanded a "real" phone system that could distribute calls evenly across the support team, so Mark called up several local phone system vendors and asked for quotes. Much to his surprise, the responses all came back well above $50,000 -- far more than Mark had budgeted for the project. Far more than LSS could afford. Rather than give in and take out a small business loan, Mark made a fateful decision. He decided to write his own phone system. Why not? A phone system is really just a computer running phone software, right? Fortunately for us, Mark had no idea how big a project he had take on. If he had known what a massive undertaking it was to build a phone system from the ground up might have gritted his teeth, borrowed the money and spent the next decade doing Linux support. But he didn't know what he didn't know, and so he started to code. And he coded. And he coded. Mark had done his engineering co-op at Adtran, a communications and networking device manufacturer in Huntsville, AL. There he had cut his teeth on telecommunications system development, solving difficult problems generating a prodigious amount of complex code in short time. This experience proved invaluable as he began to frame out the system which grew into Asterisk. In only a few months Mark crafted the original Asterisk core code. As soon as he had a working prototype he published the source code on the Internet, making it available under the GPL license (the same license used for Linux). Within a few months the idea of an "open source PBX" caught on. There had been a few other open source communications projects, but none had captured the imagination of the global population of communications geeks like Asterisk. As Mark labored on the core system, hundreds (now thousands) of developers from all over the world began to submit new features and functions. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 10 Beginning Asterisk Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 11 Installing Asterisk Now that you know a bit about Asterisk and how it is used, it's time to get you up and running with your own Asterisk installation. There are various ways to get started with Asterisk on your own system: Install an Asterisk-based Linux distribution such as AsteriskNOW. This takes care of installing Linux, Asterisk, and some web-based interfaces all at the same time, and is the easiest way to get started if you're new to Linux and/or Asterisk. If you're already familiar with Linux or Unix, you can simply install packages for Asterisk and its related tools using the package manager in your operating system. We'll cover this in more detail below in Alternate Install Methods. For the utmost in control of your installation, you can compile and install Asterisk (and its related tools) from source code. We'll explain how to do this in Installing Asterisk From Source. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 12 Installing AsteriskNOW Thank you for downloading AsteriskNOW. This Linux distribution has been carefully customized and tested with Asterisk, and installs all of the packages needed for its use. It is the officially recommended development and runtime platform for Asterisk and Digium hardware, including Digium phones. This guide provides a brief overview of installation, configuration, and maintenance of your system. More information is available at http://wiki.centos.org/. Please report any bugs at https://issues.asterisk.org/jira Installation Burn the AsteriskNOW DVD image to DVD disc and then boot from the DVD to begin the installation process. If you are unfamiliar with burning disc images, the Ubuntu community has a great Burning ISO Howto available at https://help.ub untu.com/community/BurningIsoHowto. If you are unfamiliar with booting to DVD, the Ubuntu community has a wonderful Boot From DVD HOWTO available at https://he lp.ubuntu.com/community/BootFromCD. After booting from the AsteriskNOW DVD, you will be presented with the following screen and options for an installation with, or without the FreePBX web interface. This QuickStart assumes that the FreePBX web interface has been installed. To do this, selection option 1 and press : This will begin the automated graphical installation process. During the installation, you are first presented with an option for setting the system Time Zone: Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 13 ** Choose the location that is nearest to you and move to the next screen. Next, you will be prompted to set a root password: Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 14 The 'root' user is the administrative account for Linux systems. Most system configuration requires 'root' access. If this password is lost, it is impossible to recover. It is recommend that your password contain a mix of lowercase and UPPERCASE letters, numbers, and/or symbols. Or, if you're into entropy, try a pass phrase. Then, you will choose your Hard Disk Layout: Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 15 It is recommended to select "Use All Space" and move to the next screen. Now, sit back, relax, have a cup of coffee and wait while the system is installed. This will take approximately 15-30 minutes. You will see a progress bar indicating the installation status. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 16 Once installation has completed, you will be prompted to reboot into your installation: Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 17 After the system reboots you will see this screen: Congratulations! You have successfully installed AsteriskNOW. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 18 Notice the text that says "To configure AsteriskNOW with FreePBX, point your web browser to http://xx.xx.xx.xx/." Write this down, you will need it in the next section. Now, before you move on, it is important to update your AsteriskNOW system to the latest Linux packages. To do this, use the yum utility "yum." Perform a "yum update" ** If new packages are available for installation, the utility will ask permission to install them. And, if the utility has not been run before, it may ask permission to accept a yum key. You should accept both to stay up to date. You are now ready to move on to configuration of AsteriskNOW from the FreePBX web interface. FreePBX Configuration To configure your system using FreePBX, open a web browser on another PC to the address specified during boot, e.g. "To configure AsteriskNOW with FreePBX, point your web browser to http://xx.xx.xx.xx/. If successful, you will be presented with the FreePBX main screen: Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 19 From here, we want the "FreePBX Administration" link. Click it, and you will see the FreePBX login screen: The default username is admin The default password is admin Having successfully logged into FreePBX, you will see the FreePBX dashboard: Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 20 Notice the Red reload button. It will appear after changes are made to any page. If you see it, it should be clicked, it will affect any changes on the system that FreePBX needs to make. This guide assumes that whenever you see it, you will click it. Next, we will change the default admin password. This is imperative! Failure to do this is inviting disaster. The importance of doing this C ANNOT be understated. First, visit the Admin tool Next, select admin from the right column Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 21 Then, change the admin password Finally, one should update any out of date modules on the system. To do this, we will visit the Module Admin tool: Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 22 Click the Check Online button and you will see any out of date modules To update a module, click it, and then select the Download option Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 23 Finally, press the Process button and follow the instructions to complete the module update. Updating, Querying, Removing Packages After completing installation of AsteriskNOW, all of the packages for running Asterisk are installed. However system updates are often available. AsteriskNOW contains several yum repositories in addition to the ones provided by CentOS. These are asterisk-current/asterisk-tested and digium-current/digium-tested. The asterisk- repositories contain packages for Digium-provided Open Source software (such as Asterisk, libpri, and DAHDI). The digium- repositories contain non-free or commercial software (such as the Digium Phone module for Asterisk, G.729 for Asterisk, Fax For Asterisk, and the HPEC echo cancellation module). This allows you to install additional software and to stay up to date with the latest changes. Packages can be installed or removed by using `yum install ` or `yum remove `. Updates should be regularly installed by using `yum update`. For a very full list of available and installed packages, you can use `yum list | less`. For more information about Yum, visit http://yum.baseurl.org/wi ki/YumCommands or type `man yum`. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 24 Alternate Install Methods If you already have a Linux system that you can dedicate to Asterisk, simply use the package manager in your operating system to install Asterisk, DAHDI, and libpri. Most modern Linux distributions such as Debian, Ubuntu, and Fedora have these packages in their repositories. Packages for Red Hat Enterprise Linux and CentOS are also available at http://packages.asterisk.org/ (see Asterisk Packages for instructions on use). Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 25 Validating Your AsteriskNOW Installation Before continuing on, let's check a few things to make sure your system is in good working order. First, let's make sure the DAHDI drivers are loaded. After logging in as the root user you can use the lsmod under Linux to list all of the loaded kernel modules, and the grep command to filter the input and only show the modules that have dahdi in their name. [root@server asterisk-1.6.X.Y]# lsmod | grep dahdi If the command returns nothing, then DAHDI has not been started. Start DAHDI by running: [root@server asterisk-1.6.X.Y]# service dadhi start If you have DAHDI running, the output of lsmod | grep dahdi should look something like the output below. (The exact details may be different, depending on which DAHDI modules have been built, and so forth.) [root@server ~]# lsmod | grep dahdi dahdi_dummy 4288 0 dahdi_transcode 7928 1 wctc4xxp dahdi_voicebus 40464 2 wctdm24xxp,wcte12xp dahdi 196544 12 dahdi_dummy,wctdm24xxp,wcte11xp,wct1xxp,wcte12xp,wct4xxp crc_ccitt 2096 1 dahdi Now that DAHDI is running, you can run dahdi_hardware to list any DAHDI-compatible devices in your system. You can also run the dahdi_tool utility to show the various DAHDI-compatible devices, and their current state. To check if Asterisk is running, you can use the Asterisk initscript. [root@server ~]# service asterisk status asterisk is stopped To start Asterisk, we'll use the initscript again, this time giving it the start action: [root@server ~]# service asterisk start Starting asterisk: When Asterisk starts, it runs as a background service (or daemon), so you typically won't see any response on the command line. We can check the status of Asterisk and see that it's running by using the command below. (The process identifier, or pid, will obviously be different on your system.) [root@server ~]# service asterisk status asterisk (pid 32117) is running... And there you have it... you have an Asterisk system up and running! You should now continue on in Section 202. Getting Started with Asterisk. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 26 Asterisk Configuration Files Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 27 Intro to Asterisk Configuration Files In this section, we'll introduce you to the Asterisk configuration files, and show you how to use some advanced features. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 28 Config File Format Asterisk is a very flexible telephony engine. With this flexibility, however, comes a bit of complexity. Asterisk has quite a few configuration files which control almost every aspect of how it operates. The format of these configuration files, however, is quite simple. The Asterisk configuration files are plain text files, and can be edited with any text editor. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 29 Sections and Settings The configuration files are broken into various section, with the section name surrounded by square brackets. Section names should not contain spaces, and are case sensitive. Inside of each section, you can assign values to various settings. In general, settings in one section are independent of values in another section. Some settings take values such as true or false, while other settings have more specific settings. The syntax for assigning a value to a setting is to write the setting name, an equals sign, and the value, like this: [section-name] setting=true [another_section] setting=false setting2=true Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 30 Objects Some Asterisk configuration files also create objects. The syntax for objects is slightly different than for settings. To create an object, you specify the type of object, an arrow formed by the equals sign and a greater-than sign (=>), and the settings for that object. [section-name] some_object => settings Confused by Object Syntax? In order to make life easier for newcomers to the Asterisk configuration files, the developers have made it so that you can also create objects with an equal sign. Thus, the two lines below are functionally equivalent. some_object => settings some_object=settings It is common to see both versions of the syntax, especially in online Asterisk documentation and examples. This book, however, will denote objects by using the arrow instead of the equals sign. [section-name] label1=value1 label2=value2 object1 => name1 label1=value0 label3=value3 object2 => name2 In this example, object1 inherits both label1 and label2. It is important to note that object2 also inherits label2, along with label1 (with the new overridden value value0) and label3. In short, objects inherit all the settings defined above them in the current section, and later settings override earlier settings. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 31 Comments We can (and often do) add comments to the Asterisk configuration files. Comments help make the configuration files easier to read, and can also be used to temporarily disable certain settings. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 32 Comments on a Single Line Single-line comments begin with the semicolon (;) character. The Asterisk configuration parser treats everything following the semicolon as a comment. To expand on our previous example: [section-name] setting=true [another_section] setting=false ; this is a comment ; this entire line is a comment ;awesome=true ; the semicolon on the line above makes it a ; comment, disabling the setting Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 33 Block Comments Asterisk also allows us to create block comments. A block comment is a comment that begins on one line, and continues for several lines. Block comments begin with the character sequence ;-and continue across multiple lines until the character sequence --; is encountered. The block comment ends immediately after --; is encountered. [section-name] setting=true ;-- this is a block comment that begins on this line and continues across multiple lines, until we get to here --; Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 34 Using The include and exec Constructs There are two other constructs we can use within our configuration files. They are #include and #exec. The #include construct tells Asterisk to read in the contents of another configuration file, and act as though the contents were at this location in this configuration file. The syntax is #include filename, where filename is the name of the file you'd like to include. This construct is most often used to break a large configuration file into smaller pieces, so that it's more manageable. The #exec takes this one step further. It allows you to execute an external program, and place the output of that program into the current configuration file. The syntax is #exec program, where program is the name of the program you'd like to execute. Enabling #exec Functionality The #exec construct is not enabled by default, as it has some risks both in terms of performance and security. To enable this functionality, go to the asterisk.conf configuration file (by default located in /etc/asterisk) and set execincludes=yes in the [options] section. By default both the [ options] section heading and the execincludes=yes option have been commented out, you you'll need to remove the semicolon from the beginning of both lines. Let's look at example of both constructs in action. [section-name] setting=true #include otherconfig.conf #exec otherprogram ; include another configuration file ; include output of otherprogram Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 35 Adding to an existing section If you want to add settings to an existing section of a configuration file (either later in the file, or when using the #include and #exec constructs), add a plus sign in parentheses after the section heading, as shown below: [section-name] setting1=value1 [section-name](+) setting2=value2 This example shows that the setting2 setting was added to the existing section of the configuration file. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 36 Templates Another construct we can use within most Asterisk configuration files is the use of templates. A template is a section of a configuration file that is only used as a base (or template, as the name suggests) to create other sections from. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 37 Template Syntax To define a section as a template, place an exclamation mark in parentheses after the section heading, as shown in the example below. [template-name](!) setting=value Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 38 Using Templates To use a template when creating another section, simply put the template name in parentheses after the section heading name, as shown in the example below. If you want to inherit from multiple templates, use commas to separate the template names). [template-name](!) setting=value [template-2](!) setting2=value2 [section-name](template-name,template-2) setting3=value3 The newly-created section will inherit all the values and objects defined in the template(s), as well as any new settings or objects defined in the newly-created section. The settings and objects defined in the newly-created section override settings or objects of the same name from the templates. Consider this example: [test-one](!) permit=192.168.0.2 host=alpha.example.com deny=192.168.0.1 [test-two](!) permit=192.168.1.2 host=bravo.example.com deny=192.168.1.1 [test-three](test-one,test-two) permit=192.168.3.1 host=charlie.example.com The [test-three] section will be processed as though it had been written in the following way: [test-three] permit=192.168.0.2 host=alpha.example.com deny=192.168.0.1 permit=192.168.1.2 host=bravo.example.com deny=192.168.1.1 permit=192.168.3.1 host=charlie.example.com Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 39 Basic PBX Functionality In this section, we're going to guide you through the basic setup of a very primitive PBX. After you finish, you'll have a basic PBX with two phones that can dial each other. In later modules, we'll go into more detail on each of these steps, but in the meantime, this will give you a basic system on which you can learn and experiement. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 40 The Most Basic PBX While it won't be anything to brag about, this basic PBX that you will build from Asterisk will help you learn the fundamentals of configuring Asterisk. For this exercise, we're going to assume that you have access to two phones which speak the SIP voice-over-IP protocol. There are a wide variety of SIP phones available in many different shapes and sizes, and if your budget doesn't allow for you to buy phones, feel free to use a free soft phone. Soft phones are simply computer programs which run on your computer and emulate a real phone, and communicate with other devices across your network, just like a real voice-over-IP phone would. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 41 Creating SIP Accounts In order for our two phones to communicate with each other, we need to configure an account for each phone in the channel driver which corresponds to the protocol they'll be using. Since both the phones are using the SIP protocol, we'll configure accounts in the SIP channel driver configuration file, called si p.conf. (This file resides in the Asterisk configuration directory, which is typically /etc/asterisk.) Let's name your phones Alice and Bob, so that we can easily differentiate between them. Open sip.conf with your favorite text editor, and spend a minute or two looking at the file. (Don't let it overwhelm you — the sample sip.conf has a lot of data in it, and can be overwhelming at first glance.) Notice that there are a couple of sections at the top of the configuration, such as [general] and [authentication], which control the overall functionality of the channel driver. Below those sections, there are sections which correspond to SIP accounts on the system. Scroll to the bottom of the file, and add a section for Alice and Bob. You'll need to choose your own unique password for each account, and change the permit line to match the settings for your local network. [demo-alice] type=friend host=dynamic secret=verysecretpassword ; put a strong, unique password here instead context=users deny=0.0.0.0/0 permit=192.168.5.0/255.255.255.0 ; replace with your network settings [demo-bob] type=friend host=dynamic secret=othersecretpassword ; put a strong, unique password here instead context=users deny=0.0.0.0/0 permit=192.168.5.0/255.255.255.0 ; replace with your network settings Be Serious About Account Security We can't stress enough how important it is for you to pick a strong password for all accounts on Asterisk, and to only allow access from trusted networks. Unfortunately, we've found many instances of people exposing their Asterisk to the internet at large with easily-guessable passwords, or no passwords at all. You could be at risk of toll fraud, scams, and other malicious behavior. For more information on Asterisk security and how you can protect yourself, check out http://www.asterisk.org/security/webinar/. After adding the two sections above to your sip.conf file, go to the Asterisk command-line interface and run the sip reload command to tell Asterisk to re-read the sip.conf configuration file. server*CLI> sip reload Reloading SIP server*CLI> Reloading Configuration Files Don't forget to reload the appropriate Asterisk configuration files after you have made changes to them. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 42 Registering Phones to Asterisk The next step is to configure the phones themselves to communicate with Asterisk. The way we have configured the accounts in the SIP channel driver, Asterisk will expect the phones to register to it. Registration is simply a mechanism where a phone communicates "Hey, I'm Bob's phone... here's my username and password. Oh, and if you get any calls for me, I'm at this particular IP address." Configuring your particular phone is obviously beyond the scope of this guide, but here are a list of common settings you're going to want to set in your phone, so that it can communicate with Asterisk: Registrar/Registration Server - The location of the server which the phone should register to. This should be set to the IP address of your Asterisk system. *SIP User Name/Account Name/Address - *The SIP username on the remote system. This should be set to demo-alice on one phone and demo-bob on the other. This username corresponds directly to the section name in square brackets in sip.conf. SIP Authentication User/Auth User - On Asterisk-based systems, this will be the same as the SIP user name above. Proxy Server/Outbound Proxy Server - This is the server with which your phone communicates to make outside calls. This should be set to the IP address of your Asterisk system. You can tell whether or not your phone has registered successfully to Asterisk by checking the output of the sip show peers command at the Asterisk CLI. If the Host column says (Unspecified), the phone has not yet registered. On the other hand, if the Host column contains an IP address and the Dyn colum n contains the letter D, you know that the phone has successfully registered. server*CLI> sip show peers Name/username Host Dyn NAT ACL Port Status demo-alice (Unspecified) D A 5060 Unmonitored demo-bob 192.168.5.105 D A 5060 Unmonitored 2 sip peers [Monitored: 0 online, 0 offline Unmonitored: 2 online, 0 offline] In the example above, you can see that Alice's phone has not registered, but Bob's phone has registered. Debugging SIP Registrations If you're having troubles getting a phone to register to Asterisk, make sure you watch the Asterisk CLI with the verbosity level set to at least three while you reboot the phone. You'll likely see error messages indicating what the problem is, like in this example: NOTICE[22214]: chan_sip.c:20824 handle_request_register: Registration from '"Alice"  ' failed for '192.168.5.103' - Wrong password As you can see, Asterisk has detected that the password entered into the phone doesn't match the secret setting in the [demo-alice] section of sip.conf. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 43 Creating Dialplan Extensions The last things we need to do to enable Alice and Bob to call each other is to configure a couple of extensions in the dialplan. What is an Extension? When dealing with Asterisk, the term extension does not represent a physical device such as a phone. An extension is simply a set of actions in the dialplan which may or may not write a physical device. In addition to writing a phone, an extensions might be used for such things auto-attendant menus and conference bridges. In this guide we will be careful to use the words phone or device when referring to the physical phone, and extension when referencing the set of instructions in the Asterisk dialplan. Let's take a quick look at the dialplan, and then add two extensions. Open extensions.conf, and take a quick look at the file. Near the top of the file, you'll see some general-purpose sections named [general] and [globals]. Any sections in the dialplan beneath those two sections is known as a context. The sample extensions.conf file has a number of other contexts, with names like [demo] and [default]. We'll cover contexts more in Dialplan Fundamentals, but for now you should know that each phone or outside connection in Asterisk points at a single context. If the dialed extension does not exist in the specified context, Asterisk will reject the call. Go to the bottom of your extensions.conf file, and add a new context named [users]. Naming Your Dialplan Contexts There's nothing special about the name users for this context. It could have been named strawberry_milkshake, and it would have behaved exactly the same way. It is considered best practice, however, to name your contexts for the types of extensions that are contained in that context. Since this context contains extensions for the users of our PBX system, we'll call our context users. Underneath that context name, we'll create an extesion numbered 6001 which attempts to ring Alice's phone for twenty seconds, and an extension 6002 wh ich attempts to rings Bob's phone for twenty seconds. [users] exten=>6001,1,Dial(SIP/demo-alice,20) exten=>6002,1,Dial(SIP/demo-bob,20) After adding that section to extensions.conf, go to the Asterisk command-line interface and tell Asterisk to reload the dialplan by typing the command dial plan reload. You can verify that Asterisk successfully read the configuration file by typing dialplan show users at the CLI. server*CLI> dialplan show users [ Context 'users' created by 'pbx_config' ] '6001' => 1. Dial(SIP/demo-alice,20) '6002' => 1. Dial(SIP/demo-bob,20) [pbx_config] [pbx_config] -= 2 extensions (2 priorities) in 1 context. =- Now we're ready to make a test call! Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 44 Making a Phone Call At this point, you should be able to pick up Alice's phone and dial extension 6002 to call Bob, and dial 6001 from Bob's phone to call Alice. As you make a few test calls, be sure to watch the Asterisk command-line interface (and ensure that your verbosity is set to a value three or higher) so that you can see the messages coming from Asterisk, which should be similar to the ones below: server*CLI> -- Executing [6002@users:1] Dial("SIP/demo-alice-00000000", "SIP/demo-bob,20") in new stack -- Called demo-bob -- SIP/demo-bob-00000001 is ringing -- SIP/demo-bob-00000001 answered SIP/demo-alice-00000000 -- Native bridging SIP/demo-alice-00000000 and SIP/demo-bob-00000001 == Spawn extension (users, 6002, 1) exited non-zero on 'SIP/demo-alice-00000000' As you can see, Alice called extension 6002 in the [users] context, which in turn used the Dial application to call Bob's phone. Bob's phone rang, and then answered the call. Asterisk then bridged the two calls (one call from Alice to Asterisk, and the other from Asterisk to Bob), until Alice hung up the phone. At this point, you have a very basic PBX. It has two extensions which can dial each other, but that's all. Before we move on, however, let's review a few basic troubleshooting steps that will help you be more successful as you learn about Asterisk. Basic PBX Troubleshooting The most important troubleshooting step is to set your verbosity level to three (or higher), and watch the command-line interface for errors or warnings as calls are placed. To ensure that your SIP phones are registered, type sip show peers at the Asterisk CLI. To see which context your SIP phones will send calls to, type sip show users. To ensure that you've created the extensions correctly in the [users] context in the dialplan, type dialplan show users. To see which extension will be executed when you dial extension 6002, type dialplan show 6002@users. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 45 Sound Prompt Searching based on Channel Language Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 46 Dialplan Fundamentals The dialplan is essential to the operation of any successful Asterisk system. In this module, we'll help you learn the fundamental components of the Asterisk dialplan, and how to combine them to begin scripting your own dialplan. We'll also add voice mail and a dial-by-name directory features to your dialplan. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 47 Contexts, Extensions, and Priorities The dialplan is organized into various sections, called contexts. Contexts are the basic organizational unit within the dialplan, and as such, they keep different sections of the dialplan independent from each other. We'll use contexts to enforce security boundaries between the various parts of our dialplan, as well as to provide different classes of service to groups of users. The syntax for a context is exactly the same as any other section heading in the configuration files, as explained in Section 206.2.1. Sections and Settings. Simply place the context name in square brackets. For example, here is the context we defined in the previous module: [users] Within each context, we can define one or more extensions. As explained in the previous module, an extension is simply a named set of actions. Asterisk will perform each action, in sequence, when that extension number is dialed. The syntax for an extension is: exten => number,priority,application([parameter[,parameter2...]]) As an example, let's review extension 6001 from the previous module. It looks like: exten => 6001,1,Dial(SIP/demo-alice,20) In this case, the extension number is 6001, the priority number is 1, the application is Dial(), and the two parameters to the application are SIP/demo-alice and 20. Within each extension, there must be one or more priorities. A priority is simply a sequence number. The first priority on an extension is executed first. When it finishes, the second priority is executed, and so forth. Priority numbers Priority numbers must begin with 1, and must increment sequentially. If Asterisk can't find the next priority number, it will terminate the call. We call this auto-fallthrough. Consider the example below: exten => 6123,1,do something exten => 6123,2,do something else exten => 6123,4,do something different In this case, Asterisk would execute priorites one and two, but would then terminate the call, because it couldn't find priority number three. Priority number can also be simplied by using the letter n in place of the priority numbers greater than one. The letter n stands for next, and when Asterisk sees priority n it replaces it in memory with the previous priority number plus one. Note that you must still explicitly declare priority number one. exten => 6123,1,do something exten => 6123,n,do something else exten => 6123,n,do something different You can also assign a label (or alias) to a particular priority number by placing the label in parentheses directly after the priority number, as shown below. Labels make it easier to jump back to a particular location within the extension at a later time. exten => 6123,1,do something exten => 6123,n(repeat),do something else exten => 6123,n,do something different Here, we've assigned a label named repeat to the second priority. Included in the Asterisk 1.6.2 branch (and later) there is a way to avoid having to repeat the extension name/number or pattern using the same => prefix. exten => _1NXXNXXXXXX,1,do something same => n(repeat),do something else same => n,do something different Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 48 Applications Each priority in the dialplan calls an application. An application does some work on the channel, such as answering a call or playing back a sound prompt. There are a wide variety of dialplan applications available for your use. For a complete list of the dialplan applications available to your installation of Asterisk, type core show applications at the Asterisk CLI. Most applications take one or more parameters, which provide additional information to the application or change its behavior. Parameters should be separated by commas. Syntax for Parameters You'll often find examples of Asterisk dialplan code online and in print which use the pipe character or vertical bar character (|) between parameters, as shown in this example: exten => 6123,1,application(one|two|three) This is a deprecated syntax, and will no longer work in newer versions of Asterisk. Simply replace the pipe character with a comma, like this: exten => 6123,1,application(one,two,three) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 49 Answer, Playback, and Hangup Applications As its name suggests, the Answer() application answers an incoming call. The Answer() application takes a delay (in milliseconds) as its first parameter. Adding a short delay is often useful for ensuring that the remote endpoing has time to begin processing audio before you play a sound prompt. Otherwise, you may not hear the very beginning of the prompt. Knowing When to Answer a Call When you're first learning your way around the Asterisk dialplan, it may be a bit confusing knowing when to use the Answer() application, and when not to. If Asterisk is simply going to pass the call off to another device using the Dial() application, you probably don't want to call the answer the call first. If, on the other hand, you want Asterisk to play sound prompts or gather input from the caller, it's probably a good idea to call the Answer() application before doing anything else. The Playback() application loads a sound prompt from disk and plays it to the caller, ignoring any touch tone input from the caller. The first parameter to the dialplan application is the filename of the sound prompt you wish to play, without a file extension. If the channel has not already been answered, Playba ck() will answer the call before playing back the sound prompt, unless you pass noanswer as the second parameter. To avoid the first few milliseconds of a prompt from being cut off you can play a second of silence. For example, if the prompt you wanted to play was hello-world which would look like this in the dialplan: exten => 1234,1,Playback(hello-world) You could avoid the first few seconds of the prompt from being cut off by playing the silence/1 file: exten => 1234,1,Playback(silence/1) exten => 1234,n,Playback(hello-world) Alternatively this could all be done on the same line by separating the filenames with an ampersand (&): exten => 1234,1,Playback(silence/1&hello-world) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 50 Early Media and the Progress Application Many dialplan applications within Asterisk support a common VOIP feature known as early media. Early Media is most frequently associated with the SIP channel, but it is also a feature of other channel drivers such as H323. In simple situations, any call in Asterisk that is going to involve audio should invoke either Progress() or Answer(). By making use of the progress application, an phone call can be made to play audio before answering a call or even without ever even intending to answer the full call. Simple Example involving playback: exten exten exten exten => => => => 500,1,Progress() 500,n,Wait(1) 500,n,Playback(WeAreClosedGoAway,noanswer) 500,n,Hangup() In the example above, we start an early media call which waits for a second and then plays a rather rudely named message indicating that the requested service has closed for whatever reason before hanging up. It is worth observing that the Playback application is called with the 'noanswer' argument. Without that argument, Playback would automatically answer the call and then we would no longer be in early media mode. Strictly speaking, Asterisk will send audio via RTP to any device that calls in regardless of whether Asterisk ever answers or progresses the call. It is possible to make early media calls to some devices without ever sending the progress message, however this is improper and can lead to a myriad of nasty issues that vary from device to device. For instance, in internal testing, there was a problem reported against the Queue application involving the following extension: exten => 500,1,Queue(queuename) This is certainly a brief example. The queue application does not perform any sort of automatic answering, so at this point Asterisk will be sending the phone audio packets, but it will not have formally answered the call or have sent a progress indication. At this point, different phones will behave differently. In the case of the internal test, our Polycom Soundpoint IP 330 phone played nothing while our SNOM360 phone played audio until approximately one minute into the call before it started ceaselessly generating a ring-back indication. There is nothing wrong with either of these phones... they are simply reacting to an oddly formed SIP dialog. Obviously though, neither of these is ideal for a queue and the problem wouldn't have existed had Queue been started after using the Progress application like below: exten => 500,1,Progress() exten => 500,n,Queue(queuename) Getting the hang of when to use Progress and Answer can be a little tricky, and it varies greatly from application to application. If you want to be safe, you can always just answer the calls and keep things simple, but there are a number of use cases where it is more appropriate to use early media, and most people who actually need this feature will probably be aware of when it is necessary. Applications which can use early media and do not automatically answer (incomplete list, please contribute): SayAlpha/SayDigits/SayNumber/etc Playback (conditionally) MP3 MixMonitor MorseCode Echo Queue MusicOnHold Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 51 Exploring Sound Prompts Asterisk comes with a wide variety of pre-recorded sound prompts. When you install Asterisk, you can choose to install both core and extra sound packages in several different file formats. Prompts are also available in several languages. To explore the sound files on your system, simply find the sounds directory (this will be /var/lib/asterisk/sounds on most systems) and look at the filenames. You'll find useful prompts ("Please enter the extension of the person you are looking for..."), as well as as a number of off-the-wall prompts (such as "Weasels have eaten our phone system", "The office has been overrun with iguanas", and "Try to spend your time on hold not thinking about a blue-eyed polar bear") as well. Sound Prompt Formats Sound prompts come in a variety of file formats, such as .wav and .ulaw files. When asked to play a sound prompt from disk, Asterisk plays the sound prompt with the file format that can most easily be converted to the CODEC of the current call. For example, if the inbound call is using the alaw CODEC and the sound prompt is available in .gsm and .ulaw format, Asterisk will play the .ulaw file because it requires fewer CPU cycles to transcode to the alaw CODEC. You can type the command core show translation at the Asterisk CLI to see the transcoding times for various CODECs. The times reported (in Asterisk 1.6.0 and later releases) are the number of microseconds it takes Asterisk to transcode one second worth of audio. These times are calculated when Asterisk loads the codec modules, and often vary slightly from machine to machine. To perform a current calculation of translation times, you can type the command core show translation recalc 60. How Asterisk Searches for Sound Prompts Based on Channel Language Each channel in Asterisk can be assigned a language by the channel driver. The channel's language code is split, piece by piece (separated by underscores), and used to build paths to look for sound prompts. Asterisk then uses the first file that is found. This means that if we set the language to en_GB_female_BT, for example, Asterisk would search for files in: .../sounds/en/GB/female/BT .../sounds/en/GB/female .../sounds/en/GB .../sounds/en .../sounds This scheme makes it easy to add new sound prompts for various language variants, while falling back to a more general prompt if there is no prompt recorded in the more specific variant. The Hangup() application hangs up the current call. While not strictly necessary due to auto-fallthrough (see the note on Priority numbers above), in general we recommend you add the Hangup() application as the last priority in any extension. Now let's put Answer(), Playback(), and Hangup() together to play a sample sound file. Place this extension in your [docs:users] context: exten => 6000,1,Answer(500) exten => 6000,n,Playback(hello-world) exten => 6000,n,Hangup() Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 52 Dial Application Now that you've learned the basics of using dialplan applications, let's take a closer look at the Dial() application that we used earlier in extensions 6001 an d 6002. Dial() attempts to ring an external device, and if the call is answered it bridges the two channels together and does any necessary protocol or CODEC conversion. It also handles call progress responses (busy, no-answer, ringing). Dial() and the Dialplan Please note that if the Dial() application successfully bridges two channels together, that the call does not progress in the dialplan. The call will only continue on to the next priority if the Dial() application is unable to bridge the calling channel to the dialed device. The Dial() application takes four parameters: 1. Devices A list of the device(s) you want to call. Devices are specified as technology or channel driver, a forward slash, and the device or account name. For example, SIP/demo-alice would use the SIP channel driver to call the device specified in the demo-alice sec tion of sip.conf. Devices using the IAX2 channel driver take the form of IAX2/demo-george, and DAHDI channels take the form of DAHDI/1. When calling through a device (such as a gateway) or service provider to reach another number, the syntax is technology/devic e/number such as SIP/my_provider/5551212 or DAHDI/4/5551212. To dial multiple devices at once, simply concatenate the devices together whith the ampersand character (&). The first device to answer will get bridged with the caller, and the other endpoints will stop ringing. exten => 6003,1,Dial(SIP/demo-alice&SIP/demo-bob,30) 2. Timeout The number of seconds to allow the device(s) to ring before giving up and moving on to the next priority in the extension. 3. Options There are dozens of options that you can set on the outbound call, including call screening, distinctive ringing and more. Type co re show application dial at the Asterisk CLI for a complete list of all available options. If you want to specify multiple options, simply concatenate them together. For example, if you want to use both the *m*and H options, you would set mH as the options parameter. 4. URL The fourth parameter is a URL that will be sent to the endpoint. Few endpoints do anything with the URL, but there are a few (softphones mostly) that do act on the URL. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 53 Adding Voice Mail to Dialplan Extensions Adding voicemail to the extensions is quite simple. The Asterisk voicemail module provides two key applications for dealing with voice mail. The first, named VoiceMail(), allows a caller to leave a voice mail message in the specified mailbox. The second, called VoiceMailMain(), allows the mailbox owner to retrieve their messages and change their greetings. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 54 VoiceMail Application The VoiceMail() applications takes two parameters: 1. Mailbox This parameter specifies the mailbox in which the voice mail message should be left. It should be a mailbox number and a voice mail context concatenated with an at-sign (@), like 6001@default. (Voice mail boxes are divided out into various voice mail context, similar to the way that extensions are broken up into dialplan contexts.) If the voice mail context is omitted, it will default to the default voice mail context. 2. Options One or more options for controlling the mailbox greetings. The most popular options include the u option to play the unavailable message, the b option to play the busy message, and the s option to skip the system-generated instructions. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 55 VoiceMailMain Application The VoiceMailMain() application allows the owner of a voice mail box to retrieve their messages, as well as set mailbox options such as greetings and their PIN number. The VoiceMailMain() application takes two parameters: 1. Mailbox - This parameter specifies the mailbox to log into. It should be a mailbox number and a voice mail context, concatenated with an at-sign (@), like 6001@default. If the voice mail context is omitted, it will default to the default voice mail context. If the mailbox number is omitted, the system will prompt the caller for the mailbox number. 2. Options - One or more options for controlling the voicemail system. The most popular option is the s option, which skips asking for the PIN number Direct Access to Voice mail Please exercise extreme caution when using the s option! With this option set, anyone which has access to this extension can retrieve voicemail messages without entering the mailbox passcode. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 56 Configuring Voice Mail Boxes Now that we've covered the two main voice mail applications, let's look at the voicemail configuration. Voice mail options and mailboxes are configured in the voicemail.conf configuration file. This file has three major sections: The [general] section Near the top of voicemail.conf, you'll find the [general] section. This section of the configuration file controls the general aspects of the voicemail system, such as the maximum number of messages per mailbox, the maximum length of a voicemail message, and so forth. Feel free to look at the sample voicem ail.conf file for more details about the various settings. The [zonemessages] section The [zonemessages] section is used to define various timezones around the world. Each mailbox can be assigned to a particular time zone, so that times and dates are announced relative to their local time. The time zones specified in this section also control the way in which times and dates are announced, such as reading the time of day in 24-hour format. Voice Mail Contexts After the [general] and [zonemessages] sections, any other bracketed section is a voice mail context. Within each context, you can define one or more mailbox. To define a mailbox, we set a mailbox number, a PIN, the mailbox owner's name, the primary email address, a secondary email address, and a list of mailbox options (separated by the pipe character), as shown below: mailbox=>pin,full name,email address,short email address,mailbox options By way of explanation, the short email address is an email address that will receive shorter email notifications suitable for mobile devices such as cell phones and pagers. It will never receive attachments. To add voice mail capabilities to extensions 6001 and 6002, add these three lines to the bottom of voicemail.conf. [vm-demo] 6001 => 8762,Alice Jones,alice@example.com,alice2@example.com,attach=no|tz=central|maxmsg=10 6002 => 9271,Bob Smith,bob@example.com,bob2@example.com,attach=yes|tz=eastern Now that we've defined the mailboxes, we can go into the Asterisk CLI and type voicemail reload to get Asterisk to reload the voicemail.conf file. We can also verify that the new mailboxes have been created by typing voicemail show users. server*CLI> voicemail reload Reloading voicemail configuration... server*CLI> voicemail show users Context Mbox User default general New User default 1234 Example Mailbox other 1234 Company2 User vm-demo 6001 Alice Jones vm-demo 6002 Bob Smith 5 voicemail users configured. Zone central eastern NewMsg 0 0 0 0 0 Now that we have mailboxes defined, let's add a priority to extensions 6001 and 6002 which will allow callers to leave voice mail in their respective mailboxes. We'll also add an extension 6500 to allow Alice and Bob to check their voicemail messages. Please modify your [users] context in extensions. conf to look like the following: Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 57 [users] exten => 6000,1,Answer(500) exten => 6000,n,Playback(hello-world) exten => 6000,n,Hangup() exten => 6001,1,Dial(SIP/demo-alice,20) exten => 6001,n,VoiceMail(6001@vm-demo,u) exten => 6002,1,Dial(SIP/demo-bob,20) exten => 6002,n,VoiceMail(6002@vm-demo,u) exten => 6500,1,Answer(500) exten => 6500,n,VoiceMailMain(@vm-demo) Reload the dialplan by typing dialplan reload at the Asterisk CLI. You can then test the voice mail system by dialing from one phone to the other and waiting twenty seconds. You should then be connected to the voicemail system, where you can leave a message. You should also be able to dial extension 6500 to retrieve the voicemail message. When prompted, enter the mailbox number and PIN number of the mailbox. While in the VoiceMainMain() application, you can also record the mailbox owner's name, unavailable greeting, and busy greeting by pressing 0 at the voicemail menu. Please record at least the name greeting for both Alice and Bob before continuing on to the next section. Go into lots of detail about the voicemail interface? How to move between messages, move between folders, forward messages, etc? Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 58 Directory Application The next application we'll cover is named Directory(), because it presents the callers with a dial-by-name directory. It asks the caller to enter the first few digits of the person's name, and then attempts to find matching names in the specified voice mail context in voicemail.conf. If the matching mailboxes have a recorded name greeting, Asterisk will play that greeting. Otherwise, Asterisk will spell out the person's name letter by letter. Directory([voicemail_context,[dialplan_context,[options]]]) The Directory() application takes three parameters: voicemail_context This is the context within voicemail.conf in which to search for a matching directory entry. If not specified , the [docs:default] context will be searched. dialplan_context When the caller finds the directory entry they are looking for, Asterisk will dial the extension matching their mailbox in this context. options A set of options for controlling the dial-by-name directory. Common options include f for searching based on first name instead of last name and e to read the extension number as well as the name. Directory() Options To see the complete list of options for the Directory() application, type core show application Directory at the Asterisk CLI. Let's add a dial-by-name directory to our dialplan. Simply add this line to your [docs:users] context in extensions.conf: exten => 6501,1,Directory(vm-demo,users,ef) Now you should be able to dial extension 6501 to test your dial-by-name directory. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 59 Auto-attendant and IVR Menus In this section, we'll cover the how to build voice menus, often referred to as auto-attedants and IVR menus. IVR stands for Interactive Voice Response, and is used to describe a system where a caller navigates through a system by using the touch-tone keys on their phone keypad. When the caller presses a key on their phone keypad, the phone emits two tones, known as DTMF tones. DTMF stands for Dual Tone Multi-Frequency. Asterisk recognizes the DTMF tones and responds accordingly. For more information on DTMF tones, see Section 440.3. DTMF Dialing. Let's dive in and learn how to build IVR menus in the Asterisk dialplan! Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 60 Background and WaitExten Applications The Background() application plays a sound prompt, but listens for DTMF input. Asterisk then tries to find an extension in the current dialplan context that matches the DTMF input. If it finds a matching extension, Asterisk will send the call to that extension. The Background() application takes the name of the sound prompt as the first parameter just like the Playback() application, so remember not to include the file extension. Multiple Prompts If you have multiple prompts you'd like to play during the Background() application, simply concatenate them together with the ampersand (&) character, like this: exten => 6123,1,Background(prompt1&prompt2&prompt3) One problems you may encounter with the Background() application is that you may want Asterisk to wait a few more seconds after playing the sound prompt. In order to do this, you can call the WaitExten() application. You'll usually see the WaitExten() application called immediately after the Backgroun d() application. The first parameter to the WaitExten() application is the number of seconds to wait for the caller to enter an extension. If you don't supply the first parameter, Asterisk will use the built-in response timeout (which can be modified with the TIMEOUT() dialplan function). [auto_attendant] exten => start,1,Verbose(2,Incoming call from ${CALLERID(all)}) same => n,Playback(silence/1) same => n,Background(prompt1&prompt2&prompt3) same => n,WaitExten(10) same => n,Goto(timeout-handler,1) exten => timeout-handler,1) same => n,Dial(${GLOBAL(OPERATOR)},30) same => n,Voicemail(operator@default,${IF($[${DIALSTATUS} = BUSY]?b:u)}) same => n,Hangup() Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 61 Goto Application and Priority Labels Before we create a simple auto-attendant menu, let's cover a couple of other useful dialplan applications. The Goto() application allows us to jump from one position in the dialplan to another. The parameters to the Goto() application are slightly more complicated than with the other applications we've looked at so far, but don't let that scare you off. The Goto() application can be called with either one, two, or three parameters. If you call the Goto() application with a single parameter, Asterisk will jump to the specified priority (or its label) within the current extension. If you specify two parameters, Asterisk will read the first as an extension within the current context to jump to, and the second parameter as the priority (or label) within that extension. If you pass three parameters to the application, Asterisk will assume they are the context, extension, and priority (respectively) to jump to. [StartingContext] exten => 100,1,Goto(monkeys) same => n,NoOp(We skip this) same => n(monkeys),Playback(tt-monkeys) same => n,Hangup() exten => 200,1,Goto(start,1) ; play tt-weasels then tt-monkeys exten => 300,1,Goto(start,monkeys) ; only play tt-monkeys exten => 400,1,Goto(JumpingContext,start,1) ; play hello-world exten => start,1,NoOp() same => n,Playback(tt-weasels) same => n(monkeys),Playback(tt-monkeys) [JumpingContext] exten => start,1,NoOp() same => n,Playback(hello-world) same => n,Hangup() Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 62 SayDigits, SayNumber, SayAlpha, and SayPhonetic Applications While not exactly related to auto-attendant menus, we'll introduce some applications to read back various pieces of information back to the caller. The Say Digits() and SayNumber() applications read the specified number back to caller. To use the SayDigits() and SayNumber() application simply pass it the number you'd like it to say as the first parameter. The SayDigits() application reads the specified number one digit at a time. For example, if you called SayDigits(123), Asterisk would read back "one two three". On the other hand, the SayNumber() application reads back the number as if it were a whole number. For example, if you called SayNumber(123) Asterisk would read back "one hundred twenty three". The SayAlpha() and SayPhonetic() applications are used to spell an alphanumeric string back to the caller. The SayAlpha() reads the specified string one letter at a time. For example, SayAlpha(hello) would read spell the word "hello" one letter at a time. The SayPhonetic() spells back a string one letter at a time, using the international phonetic alphabet. For example, SayPhonetic(hello) would read back "Hotel Echo Lima Lima Oscar". We'll use these four applications to read back various data to the caller througout this guide. In the meantime, please feel free to add some sample extensions to your dialplan to try out these applications. Here are some examples: exten exten exten exten => => => => 6592,1,SayDigits(123) 6593,1,SayNumber(123) 6594,1,SayAlpha(hello) 6595,1,SayPhonetic(hello) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 63 Creating a Simple IVR Menu Let's go ahead and apply what we've learned about the various dialplan applications by building a very simple auto-attendant menu. It is common practice to create an auto-attendant or IVR menu in a new context, so that it remains independant of the other extensions in the dialplan. Please add the following to your dialplan (the extensions.conf file) to create a new demo-menu context. In this new context, we'll create a simple menu that prompts you to enter one or two, and then it will read back what you're entered. Sample Sound Prompts Please note that the example below (and many of the other examples in this guide) use sound prompts that are part of the extra sounds packages. If you didn't install the extra sounds earlier, now might be a good time to do that. [demo-menu] exten => s,1,Answer(500) same => n(loop),Background(press-1&or&press-2) same => n,WaitExten() exten => 1,1,Playback(you-entered) same => n,SayNumber(1) same => n,Goto(s,loop) exten => 2,1,Playback(you-entered) same => n,SayNumber(2) same => n,Goto(s,loop) Before we can use the demo menu above, we need to add an extension to the [docs:users] context to redirect the caller to our menu. Add this line to the [ docs:users] context in your dialplan: exten => 6598,1,Goto(demo-menu,s,1) Reload your dialplan, and then try dialing extension 6598 to test your auto-attendant menu. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 64 Handling Special Extensions We have the basics of an auto-attendant created, but now let's make it a bit more robust. We need to be able to handle special situations, such as when the caller enters an invalid extension, or doesn't enter an extension at all. Asterisk has a set of special extensions for dealing with situations like there. They all are named with a single letter, so we recommend you don't create any other extensions named with a single letter. The most common special extensions include: i: the invalid entry extension If Asterisk can't find an extension in the current context that matches the digits dialed during the Background() or WaitExten() applications, it will send the call to the i extension. You can then handle the call however you see fit. t: the reponse timeout extension When the caller waits too long before entering a response to the Background() or WaitExten() applications, and there are no more priorities in the current extension, the call is sent to the t extension. s: the start extension When an analog call comes into Asterisk, the call is sent to the s extension. The s extension is also used in macros. Please note that the s extension is not a catch-all extension. It's simply the location that analog calls and macros begin. In our example above, it simply makes a convenient extension to use that can't be easily dialed from the Background() and WaitExten() applications. h: the hangup extension When a call is hung up, Asterisk executes the h extension in the current context. This is typically used for some sort of clean-up after a call has been completed. o: the operator extension If a caller presses the zero key on their phone keypad while recording a voice mail message, and the o extension exists, the caller will be redirected to the o extension. This is typically used so that the caller can press zero to reach an operator. a: the assistant extension This extension is similar to the o extension, only it gets triggered when the caller presses the asterisk (*) key while recording a voice mail message. This is typically used to reach an assistant. Let's add a few more lines to our [docs:demo-menu] context, to handle invalid entries and timeouts. Modify your [docs:demo-menu] context so that it matches the one below: [demo-menu] exten => s,1,Answer(500) same => n(loop),Background(press-1&or&press-2) same => n,WaitExten() exten => 1,1,Playback(you-entered) same => n,SayNumber(1) same => n,Goto(s,loop) exten => 2,1,Playback(you-entered) same => n,SayNumber(2) same => n,Goto(s,loop) exten => i,1,Playback(option-is-invalid) same => n,Goto(s,loop) exten => t,1,Playback(are-you-still-there) same => n,Goto(s,loop) Now dial your auto-attendant menu again (by dialing extension 6598), and try entering an invalid option (such as 3) at the auto-attendant menu. If you watch the Asterisk command-line interface while you dial and your verbosity level is three or higher, you should see something similar to the following: Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 65 ----------------- Executing [6598@users:1] Goto("SIP/demo-alice-00000008", "demo-menu,s,1") in new stack Goto (demo-menu,s,1) Executing [s@demo-menu:1] Answer("SIP/demo-alice-00000008", "500") in new stack Executing [s@demo-menu:2] BackGround("SIP/demo-alice-00000008", "press-1&or&press-2") in new stack Playing 'press-1.gsm' (language 'en') Playing 'or.gsm' (language 'en') Playing 'press-2.gsm' (language 'en') Invalid extension '3' in context 'demo-menu' on SIP/demo-alice-00000008 Executing [i@demo-menu:1] Playback("SIP/demo-alice-00000008", "option-is-invalid") in new stack Playing 'option-is-invalid.gsm' (language 'en') Executing [i@demo-menu:2] Goto("SIP/demo-alice-00000008", "s,loop") in new stack Goto (demo-menu,s,2) Executing [s@demo-menu:2] BackGround("SIP/demo-alice-00000008", "press-1&or&press-2") in new stack Playing 'press-1.gsm' (language 'en') Playing 'or.gsm' (language 'en') Playing 'press-2.gsm' (language 'en') If you don't enter anything at the auto-attendant menu and instead wait approximately ten seconds, you should hear (and see) Asterisk go to the t extensio n as well. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 66 Record Application For creating your own auto-attendant or IVR menus, you're probably going to want to record your own custom prompts. An easy way to do this is with the R ecord() application. The Record() application plays a beep, and then begins recording audio until you press the hash key ( #) on your keypad. It then saves the audio to the filename specified as the first parameter to the application and continues on to the next priority in the extension. If you hang up the call before pressing the hash key, the audio will not be recorded. For example, the following extension records a sound prompt called custom-menu in the gs m format in the en/ sub-directory, and then plays it back to you. exten => 6597,1,Answer(500) same => n,Record(en/custom-menu.gsm) same => n,Wait(1) same => n,Playback(custom-menu) same => n,Hangup() Recording Formats When specifiying a file extension when using the Record() application, you must choose a file extension which represents one of the supported file formats in Asterisk. For the complete list of file formats supported in your Asterisk installation, type core show file formats at the Asterisk command-line interface. You've now learned the basics of how to create a simple auto-attendant menu. Now let's build a more practical menu for callers to be able to reach Alice or Bob or the dial-by-name directory. Procedure 216.1. Building a Practical Auto-Attendant Menu 1. Add an extension 6599 to the [docs:users] context which sends the calls to a new context we'll build called [docs:day-menu]. Your extension should look something like: exten=>6599,1,Goto(day-menu,s,1) 2. Add a new context called [docs:day-menu], with the following contents: [day-menu] exten => s,1,Answer(500) same => n(loop),Background(custom-menu) same => n,WaitExten() exten => 1,1,Goto(users,6001,1) exten => 2,1,Goto(users,6002,1) exten => 9,1,Directory(vm-demo,users,fe) exten => *,1,VoiceMailMain(@vm-demo) exten => i,1,Playback(option-is-invalid) same => n,Goto(s,loop) exten => t,1,Playback(are-you-still-there) same => n,Goto(s,loop) 1. Dial extension 6597 to record your auto-attendant sound prompt. Your sound prompt should say something like "Thank you for calling! Press one for Alice, press two for Bob, or press 9 for a company directory". Press the hash key (#) on your keypad when you're finished recording, and Asterisk will play it back to you. If you don't like it, simply dial extension 6597 again to re-record it. 2. Dial extension 6599 to test your auto-attendant menu. In just a few lines of code, you've created your own auto-attendant menu. Feel free to experiment with your auto-attendant menu before moving on to the next section. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 67 Dialplan Architecture In this section, we'll begin adding structure to our dialplan. We'll begin by talking about variables and how to use them, as well as how to manipulate them. Then we'll cover more advanced topics, such as pattern matching and using include statements to build classes of functionality. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 68 Variables Variables are used in most programming and scripting languages. In Asterisk, we can use variables to simplify our dialplan and begin to add logic to the system. A variable is simply a container that has both a name and a value. For example, we can have a variable named COUNT which has a value of three. Later on, we'll show you how to route calls based on the value of a variable. Before we do that, however, let's learn a bit more about variables. The names of variables are case-sensitive, so COUNT is different than Count and count. Any channel variables created by Asterisk will have names that are completely upper-case, but for your own channels you can name them however you would like. In Asterisk, we have two different types of variables: channel variables and global variables. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 69 Channel Variables Basics Channel variables are variables that are set for the current channel (one leg of a bridged phone call). They exist for the lifetime of the channel, and then go away when that channel is hung up. Channel variables on one particular channel are completely independent of channel variables on any other channels; in other words, two channels could each have variables called COUNT with different values. To assign a value to a channel variable, we use the Set() application. Here's an example of setting a variable called COUNT to a value of 3. exten=>6123,1,Set(COUNT=3) To retrieve the value of a variable, we use a special syntax. We put a dollar sign and curly braces around the variable name, like ${COUNT} When Asterisk sees the dollar sign and curly braces around a variable name, it substitutes in the value of the variable. Let's look at an example with the Sa yNumber() application. exten=>6123,1,Set(COUNT=3) exten=>6123,n,SayNumber(${COUNT}) In the second line of this example, Asterisk replaces the ${COUNT} text with the value of the COUNT variable, so that it ends up calling SayNumber(3). Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 70 Global Variables Basics Global variables are variables that don't live on one particular channel — they pertain to all calls on the system. They have global scope. There are two ways to set a global variable. The first is to declare the variable in the [globals] section of extensions.conf, like this: [globals] MYGLOBALVAR=somevalue You can also set global variables from dialplan logic using the GLOBAL() dialplan function along with the Set() application. Simply use the syntax: exten=>6124,1,Set(GLOBAL(MYGLOBALVAR)=somevalue) To retrieve the value of a global channel variable, use the same syntax as you would if you were retrieving the value of a channel variable. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 71 Manipulating Variables Basics It's often useful to do string manipulation on a variable. Let's say, for example, that we have a variable named NUMBER which represents a number we'd like to call, and we want to strip off the first digit before dialing the number. Asterisk provides a special syntax for doing just that, which looks like ${variable [:skip[docs::length]}. The optional skip field tells Asterisk how many digits to strip off the front of the value. For example, if NUMBER were set to a value of 98765, then ${NUMB ER:2} would tell Asterisk to remove the first two digits and return 765. If the skip field is negative, Asterisk will instead return the specified number of digits from the end of the number. As an example, if NUMBER were set to a value of 98765, then ${NUMBER:-2} would tell Asterisk to return the last two digits of the variable, or 65. If the optional length field is set, Asterisk will return at most the specified number of digits. As an example, if NUMBER were set to a value of 98765, then $ {NUMBER:0:3} would tell Asterisk not to skip any characters in the beginning, but to then return only the three characters from that point, or 987. By that same token, ${NUMBER:1:3} would return 876. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 72 Variable Inheritance Basics When building your Asterisk dialplan, it may be useful to have one channel inherit variables from another channel. For example, imagine that Alice's call has a channel variable containing an account code, and you'd like to pass that variable on to Bob's channel when Alice's call gets bridged to Bob. We call this variable inheritance. There are two levels of variable inheritance in Asterisk: single inheritance and multiple inheritance. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 73 Multiple Inheritance Multiple inheritance means that a channel variable will be inherited by created (spawned) channels, and it will continue to be inherited by any other channels created by the spawned channels. To set multiple inheritance on a channel, preface the variable name with two underscores when giving it a value with the Set() application, as shown below. exten=>6123,1,Set(__ACCOUNT=5551212) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 74 Single Inheritance Single inheritance means that a channel variable will be inherited by created (spawned) channels, but not propogate from there to any other swawned channels. To follow our example above, if Alice sets a channel variable with single inheritance and calls Bob, Bob's channel will inherit that channel variable, but the channel variable won't get inherited by any channels that might get spawned by Bob's channel (if the call gets transferred, for example). To set single inheritance on a channel, preface the variable name with an underscore when giving it a value with the Set() application, as shown below. exten=>6123,1,Set(_ACCOUNT=5551212) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 75 Using the CONTEXT, EXTEN, PRIORITY, UNIQUEID, and CHANNEL Variables Now that you've learned a bit about variables, let's look at a few of the variables that Asterisk automatically creates. Asterisk creates channel variables named CONTEXT, EXTEN, and PRIORITY which contain the current context, extension, and priority. We'll use them in pattern matching (below), as well as when we talk about macros in Section 308.10. Macros. Until then, let's show a trivial example of using ${EXTEN} to read back the current extension number. exten=>6123,1,SayNumber(${EXTEN}) If you were to add this extension to the [docs:users] context of your dialplan and reload the dialplan, you could call extension 6123 and hear Asterisk read back the extension number to you. Another channel variable that Asterisk automatically creates is the UNIQUEID variable. Each channel within Asterisk receives a unique identifier, and that identifier is stored in the UNIQUEID variable. The UNIQUEID is in the form of 1267568856.11, where 1267568856 is the Unix epoch, and 11 shows that this is the eleventh call on the Asterisk system since it was last restarted. Last but not least, we should mention the CHANNEL variable. In addition to a unique identifier, each channel is also given a channel name and that channel name is set in the CHANNEL variable. A SIP call, for example, might have a channel name that looks like SIP/george-0000003b, for example. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 76 The Verbose and NoOp Applications Asterisk has a convenient dialplan applications for printing information to the command-line interface, called Verbose(). The Verbose() application takes two parameters: the first parameter is the minimum verbosity level at which to print the message, and the second parameter is the message to print. This extension would print the current channel identifier and unique identifier for the current call, if the verbosity level is two or higher. exten=>6123,1,Verbose(2,The channel name is ${CHANNEL}) exten=>6123,n,Verbose(2,The unique id is ${UNIQUEID}) The NoOp() application stands for "No Operation". In other words, it does nothing. Because of the way Asterisk prints everything to the console if your verbosity level is three or higher, however, the NoOp() application is often used to print debugging information to the console like the Verbose() does. While you'll probably come across examples of the NoOp() application in other examples, we recommend you use the Verbose() application instead. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 77 The Read Application The Read() application allows you to play a sound prompt to the caller and retrieve DTMF input from the caller, and save that input in a variable. The first parameter to the Read() application is the name of the variable to create, and the second is the sound prompt or prompts to play. (If you want multiple prompts, simply concatenate them together with ampersands, just like you would with the Background() application.) There are some additional parameters that you can pass to the Read() application to control the number of digits, timeouts, and so forth. You can get a complete list by running the core show application read command at the Asterisk CLI. If no timeout is specified, Read() will finish when the caller presses the hash key (#) on their keypad. exten=>6123,1,Read(Digits,enter-ext-of-person) exten=>6123,n,Playback(you-entered) exten=>6123,n,SayNumber(${Digits}) In this example, the Read() application plays a sound prompt which says "Please enter the extension of the person you are looking for", and saves the captured digits in a variable called Digits. It then plays a sound prompt which says "You entered" and then reads back the value of the Digits variable. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 78 Pattern Matching The next concept we'll cover is called pattern matching. Pattern matching allows us to create extension patterns in our dialplan that match more than one possible dialed number. Pattern matching saves us from having to create an extension in the dialplan for every possible number that might be dialed. When Alice dials a number on her phone, Asterisk first looks for an extension (in the context specified by the channel driver configuration) that matches exactly what Alice dialed. If there's no exact match, Asterisk then looks for a pattern that matches. After we show the syntax and some basic examples of pattern matching, we'll explain how Asterisk finds the best match if there are two or more patterns which match the dialed number. Pattern matches always begin with an underscore. This is how Asterisk recognizes that the extension is a pattern and not just an extension with a funny name. Within the pattern, we use various letters and characters to represent sets or ranges of numbers. Here are the most common letters: X The letter X or x represents a single digit from 0 to 9. Z The letter Z or z represents any digit from 1 to 9. N The letter N or n represents a single digit from 2 to 9. Now let's look at a sample pattern. If you wanted to match all four-digit numbers that had the first two digits as six and four, you would create an extension that looks like: exten => _64XX,1,SayDigits(${EXTEN}) In this example, each X represents a single digit, with any value from zero to nine. We're essentially saying "The first digit must be a six, the second digit must be a four, the third digit can be anything from zero to nine, and the fourth digit can be anything from zero to nine". If we want to be more specific about a range of numbers, we can put those numbers or number ranges in square brackets to define a character set. For example, what if we wanted the second digit to be either a three or a four? One way would be to create two patterns ( _64XX and _63XX), but a more compact method would be to do _6[34]XX. This specifies that the first digit must be a six, the second digit can be either a three or a four, and that the last two digits can be anything from zero to nine. You can also use ranges within square brackets. For example, [1-468] would match a single digit from one through four or six or eight. It does not match any number from one to four hundred sixty-eight! Within Asterisk patterns, we can also use a couple of other characters to represent ranges of numbers. The period character ( .) at the end of a pattern matches one or more remaining characters. You put it at the end of a pattern when you want to match extensions of an indeterminate length. As an example, the pattern _9876. would match any number that began with 9876 and had at least one more character or digit. The exclamation mark (!) character is similar to the period and matches zero or more remaining characters. It is used in overlap dialing to dial through Asterisk. For example, _9876! would match any number that began with 9876 including 9876, and would respond that the number was complete as soon as there was an unambiguous match. Asterisk treats a period or exclamation mark as the end of a pattern. If you want a period or exclamation mark in your pattern as a plain character you should put it into a character set: [.] or [!]. Be Careful With Wildcards in Pattern Matches Please be extremely cautious when using the period and exclamation mark characters in your pattern matches. They match more than just digits. They match on characters. If you're not careful to filter the input from your callers, a malicious caller might try to use these wildcards to bypass security boundaries on your system. For a more complete explanation of this topic and how you can protect yourself, please refer to the README-SERIOUSLY.bestpractices.txt fil e in the Asterisk source code. Now let's show what happens when there is more than one pattern that matches the dialed number. How does Asterisk know which pattern to choose as the best match? Asterisk uses a simple set of rules to sort the extensions and patterns so that the best match is found first. The best match is simply the most specific pattern. The sorting rules are: 1. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 79 1. The dash (-) character is ignored in extensions and patterns except when it is used in a pattern to specify a range in a character set. It has no effect in matching or sorting extensions. 2. Non-pattern extensions are sorted in ASCII sort order before patterns. 3. Patterns are sorted by the most constrained character set per digit first. By most constrained, we mean the pattern that has the fewest possible matches for a digit. As an example, the N character has eight possible matches (two through nine), while X has ten possible matches (zero through nine) so N sorts first. 4. Character sets that have the same number of characters are sorted in ASCII sort order as if the sets were strings of the set characters. As an example, X is 0123456789 and [a-j] is abcdefghij so X sorts first. This sort ordering is important if the character sets overlap as with [0-4] and [4-8]. 5. The period (.) wildcard sorts after character sets. 6. The exclamation mark (!) wildcard sorts after the period wildcard. Let's look at an example to better understand how this works. Let's assume Alice dials extension 6421, and she has the following patterns in her dialplan: exten exten exten exten exten exten exten => => => => => => => _6XX1,1,SayAlpha(A) _64XX,1,SayAlpha(B) _640X,1,SayAlpha(C) _6.,1,SayAlpha(D) _64NX,1,SayAlpha(E) _6[45]NX,1,SayAlpha(F) _6[34]NX,1,SayAlpha(G) Can you tell (without reading ahead) which one would match? Using the sorting rules explained above, the extensions sort as follows: _640X sorts before _64NX because of rule 3 at position 4. (0 before N) _64NX sorts before _64XX because of rule 3 at position 4. (N before X) _64XX sorts before _6[34]NX because of rule 3 at position 3. (4 before [34]) _6[34]NX sorts before _6[45]NX because of rule 4 at position 3. ([34] before [45]) _6[45]NX sorts before _6XX1 because of rule 3 at position 3. ([45] before X) _6XX1 sorts before _6. because of rule 5 at position 3. (X before .) Sorted extensions exten exten exten exten exten exten exten => => => => => => => _640X,1,SayAlpha(C) _64NX,1,SayAlpha(E) _64XX,1,SayAlpha(B) _6[34]NX,1,SayAlpha(G) _6[45]NX,1,SayAlpha(F) _6XX1,1,SayAlpha(A) _6.,1,SayAlpha(D) When Alice dials 6421, Asterisk searches through its list of sorted extensions and uses the first matching extension. In this case _64NX is found. To verify that Asterisk actually does sort the extensions in the manner that we've shown, add the following extensions to the [users] context of your own dialplan. exten exten exten exten exten exten exten => => => => => => => _6XX1,1,SayAlpha(A) _64XX,1,SayAlpha(B) _640X,1,SayAlpha(C) _6.,1,SayAlpha(D) _64NX,1,SayAlpha(E) _6[45]NX,1,SayAlpha(F) _6[34]NX,1,SayAlpha(G) Reload the dialplan, and then type dialplan show 6421@users at the Asterisk CLI. Asterisk will show you all extensions that match in the [users] context. If you were to dial extension 6421 in the [users] context the first found extension will execute. server*CLI> dialplan show 6421@users [ Context 'users' created by 'pbx_config' ] '_64NX' => 1. SayAlpha(E) '_64XX' => 1. SayAlpha(B) '_6[34]NX' => 1. SayAlpha(G) '_6[45]NX' => 1. SayAlpha(F) '_6XX1' => 1. SayAlpha(A) '_6.' => 1. SayAlpha(D) [pbx_config] [pbx_config] [pbx_config] [pbx_config] [pbx_config] [pbx_config] -= 6 extensions (6 priorities) in 1 context. =- Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 80 server*CLI> dialplan show users [ Context 'users' created by 'pbx_config' ] '_640X' => 1. SayAlpha(C) '_64NX' => 1. SayAlpha(E) '_64XX' => 1. SayAlpha(B) '_6[34]NX' => 1. SayAlpha(G) '_6[45]NX' => 1. SayAlpha(F) '_6XX1' => 1. SayAlpha(A) '_6.' => 1. SayAlpha(D) [pbx_config] [pbx_config] [pbx_config] [pbx_config] [pbx_config] [pbx_config] [pbx_config] -= 7 extensions (7 priorities) in 1 context. =- You can dial extension 6421 to try it out on your own. Be Careful with Pattern Matching Please be aware that because of the way auto-fallthrough works, if Asterisk can't find the next priority number for the current extension or pattern match, it will also look for that same priority in a less specific pattern match. Consider the following example: exten => 6410,1,SayDigits(987) exten => _641X,1,SayDigits(12345) exten => _641X,n,SayDigits(54321) If you were to dial extension 6410, you'd hear "nine eight seven five four three two one". We strongly recommend you make the Hangup() application be the last priority of any extension to avoid this problem, unless you purposely want to fall through to a less specific match. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 81 Include Statements Include statements allow us to split up the functionality in our dialplan into smaller chunks, and then have Asterisk search multiple contexts for a dialed extension. Most commonly, this functionality is used to provide security boundaries between different classes of callers. It is important to remember that when calls come into the Asterisk dialplan, they get directed to a particular context by the channel driver. Asterisk then begins looking for the dialed extension in the context specified by the channel driver. By using include statements, we can include other contexts in the search for the dialed extension. Asterisk supports two different types of include statements: regular includes and time-based includes. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 82 Include Statements Basics To set the stage for our explanation of include statements, let's say that we want to organize our dialplan and create a new context called [docs:features]. We'll leave our extensions 6001 and 6002 for Alice and Bob in the [docs:users] context, and place extensions such as 6500 in the new [docs:features] c ontext. When calls come into the users context and doesn't find a matching extension, the include statement tells Asterisk to also look in the new [docs:fea tures] context. The syntax for an include statement is very simple. You simply write include => and then the name of the context you'd like to include from the existing context. If we reorganize our dialplan to add a [docs:features] context, it might look something like this: [users] include => features exten => 6001,1,Dial(SIP/demo-alice,20) same => n,VoiceMail(6001@vm-demo,u) exten => 6002,1,Dial(SIP/demo-bob,20) same => n,VoiceMail(6002@vm-demo,u) [features] exten => 6000,1,Answer(500) same => n,Playback(hello-world) same => n,Hangup() exten => 6500,1,Answer(500) same => n,VoiceMailMain(@vm-demo) Location of Include Statements Please note that in the example above, we placed the include statement before extensions 6001 and 6002. It could have just as well come after. Asterisk will always try to find a matching extension in the current context first, and only follow the include statement to a new context if there isn't anything that matches in the current context. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 83 Using Include Statements to Create Classes of Service Now that we've shown the basic syntax of include statements, let's put some include statements to good use. Include statements are often used to build chains of functionality or classes of service. In this example, we're going to build several different contexts, each with its own type of outbound calling. We'll then use include statements to chain these contexts together. Numbering Plans The examples in this section use patterns designed for the North American Number Plan, and may not fit your individual circumstances. Feel free to use this example as a guide as you build your own dialplan. In these examples, we're going to assuming that a seven-digit number that does not begin with a zero or a one is a local (non-toll) call. Ten-digit numbers (where neither the first or fourth digits begin with zero or one) are also treated as local calls. A one, followed by ten digits (where neither the first or fourth digits begin with zero or one) is considered a long-distance (toll) call. Again, feel free to modify these examples to fit your own particular circumstances. Outbound dialing These examples assume that you have a SIP provider named provider configured in sip.conf. The examples dial out through this SIP provider using the SIP/provider/number syntax. Obviously, these examples won't work unless you setup a SIP provider for outbound calls, or replace this syntax with some other type of outbound connection. For more information on configuring a SIP provider, see Section 420. The SIP Protocol. For analog connectivity information, see Section 441. Analog Telephony with DAHDI. For more information on connectivity via digital circuits, see Section 450. Basics of Digital Telephony First, let's create a new context for local calls. [local] ; seven-digit local numbers exten => _NXXXXXX,1,Dial(SIP/provider/${EXTEN}) ; ten-digit local numbers exten => _NXXNXXXXXX,1,Dial(SIP/provider/${EXTEN}) ; emergency services (911), and other three-digit services exten => NXX,1,Dial(SIP/provider/${EXTEN}) ; if you don't find a match in this context, look in [users] include => users Remember that the variable ${EXTEN} will get replaced with the dialed extension. For example, if Bob dials 5551212 in the local context, Asterisk will execute the Dial application with SIP/provider/5551212 as the first parameter. (This syntax means "Dial out to the account named provider using the SIP channel driver, and dial the number 5551212.) Next, we'll build a long-distance context, and link it back to the local context with an include statement. This way, if you dial a local number and your phone's channel driver sends the call to the longdistance context, Asterisk will search the local context if it doesn't find a matching pattern in the longdist ance context. [longdistance] ; 1+ ten digit long-distance numbers exten => _1NXXNXXXXXX,1,Dial(SIP/provider/${EXTEN}) ; if you don't find a match in this context, look in [local] include => local Last but not least, let's add an [docs:international] context. In North America, you dial 011 to signify that you're going to dial an international number. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 84 [international] ; 1+ ten digit long-distance numbers exten => _011.,1,Dial(SIP/provider/${EXTEN}) ; if you don't find a match in this context, look in [longdistance] include => longdistance And there we have it -- a simple chain of contexts going from most privileged (international calls) down to lease privileged (local calling). At this point, you may be asking yourself, "What's the big deal? Why did we need to break them up into contexts, if they're all going out the same outbound connection?" That's a great question! The primary reason for breaking the different classes of calls into separate contexts is so that we can enforce some security boundaries. Do you remember what we said earlier, that the channel drivers point inbound calls at a particular context? In this case, if we point a phone at the [docs:lo cal] context, it could only make local and internal calls. On the other hand, if we were to point it at the [docs:international] context, it could make international and long-distance and local and internal calls. Essentially, we've created different classes of service by chaining contexts together with include statements, and using the channel driver configuration files to point different phones at different contexts along the chain. Many people find it instructive to look at a visual diagram at this point, so let's draw ourselves a map of the contexts we've created so far. Insert graphic showing chain of includes from international through long-distance to local and to users and features In this graphic, we've illustrated the various contexts and how they work together. We've also shown that Alice's phone is pointed at the [docs:internationa l] context, while Bob's phone is only pointed at the [docs:local] context. Please take the next few minutes and implement a series of chained contexts into your own dialplan, similar to what we've explained above. You can then change the configuration for Alice and Bob (in sip.conf, since they're SIP phones) to point to different contexts, and see what happens when you attempt to make various types of calls from each phone. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 85 Installing Asterisk From Source One popular option for installing Asterisk is to download the source code and compile it yourself. While this isn't as easy as using package management or using an Asterisk-based Linux distribution, it does let you decide how Asterisk gets built, and which Asterisk modules are built. In this section, you'll learn how to download and compile the Asterisk source code, and get Asterisk installed. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 86 What to Download? On a typical system, you'll want to download three components: Asterisk DAHDI libpri The libpri library allows Asterisk to communicate with ISDN connections. (We'll cover more about ISDN connections in Section 450.8, "Intro to ISDN PRI and BRI Connections".) While not always necessary, we recommend you install it on new systems. The DAHDI library allows Asterisk to communicate with analog and digital telephones and telephone lines, including connections to the Public Switched Telephone Network, or PSTN. It should also be installed on new systems, even if you don't immediately plan on using analog or digital connections to your Asterisk system. DAHDI DAHDI stands for Digium Asterisk Hardware Device Interface, and is a set of drivers and utilities for a number of analog and digital telephony cards, such as those manufactured by Digium. The DAHDI drivers are independent of Asterisk, and can be used by other applications. DAHDI was previously called Zaptel, as it evolved from the Zapata Telephony Project. The DAHDI code can be downloaded as individual pieces (dahdi-linux for the DAHDI drivers, and dahdi-tools for the DAHDI utilities. They can also be downloaded as a complete package called dahdi-linux-complete, which contains both the Linux drivers and the utilities. Why is DAHDI split into different pieces? DAHDI has been split into two pieces (the Linux drivers and the tools) as third parties have begun porting the DAHDI drivers to other operating systems, such as FreeBSD. Eventually, we may have dahdi-linux, dahdi-freebsd, and so on. The current version of libpri, DAHDI, and Asterisk can be downloaded from http://downloads.digium.com/pub/telephony/. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 87 System Requirements In order to compile and install Asterisk, you'll need to install a C compiler and a number of system libraries on your system. Compiler System Libraries Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 88 Compiler The compiler is a program that takes source code (the code written in the C programming language in the case of Asterisk) and turns it into a program that can be executed. While any C compiler should be able to compile the Asterisk code, we strongly recommend that you use the GCC compiler. Not only is it the most popular free C compiler on Linux and Unix systems, but it's also the compiler that the Asterisk developers are using. If the GCC compiler isn't already installed on your machine, simply use appropriate package management system on your machine to install it. You'll also want to install the C++ portion of GCC as well, as certain Asterisk modules will use it. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 89 System Libraries In addition to the C compiler, you'll also need a set of system libraries. These libraries are used by Asterisk and must be installed before you can compile Asterisk. On most operating systems, you'll need to install both the library and it's corresponding development package. Development libraries For most operating systems, the development packages will have -dev or -devel on the end of the name. For example, on a Red Hat Linux system, you'd want to install both the "openssl" and "openssl-devel" packages. A list of libraries you'll need to install include: OpenSSL ncurses newt libxml2 Kernel headers (for building DAHDI drivers) We recommend you use the package management system of your operating system to install these libraries before compiling and installing libpri, DAHDI, and Asterisk. Help Finding the Right Libraries If you're installing Asterisk 1.6.1.0 or later, it comes with a shell script called install_prereq.sh in the contrib/scripts sub-directory. If you run install_prereq test, it will give you the exact commands to install the necessary system libraries on your operating system. If you run install_prereq install, it will attempt to download and install the prerequisites automatically. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 90 Untarring the Source When you download the source for libpri, DAHDI, and Asterisk you'll typically end up with files with a .tar.gz or .tgz file extension. These files are affectionately known as tarballs. The name comes from the tar Unix utility, which stands for tape archive. A tarball is a collection of other files combined into a single file for easy copying, and then often compressed with a utility such as GZip. To extract the source code from the tarballs, we'll use the tar command. The commands below assume that you've downloaded the tarballs for libpri, DAHDI, and Asterisk to the /usr/local/src directory on a Linux machine. (You'll probably need to be logged in as the root user to be able to write to that directory.) We're also going to assume that you'll replace the letters X, Y, and Z with the actual version numbers from the tarballs you downloaded. Also please note that the command prompt may be slightly different on your system than what we show here. Don't worry, the commands should work just the same. First, we'll change to the directory where we downloaded the source code: [root@server ~]# cd /usr/local/src Next, let's extract the source code from each tarball using the tar command. The -zxvf parameters to the tar command tell it what we want to do with the file. The z option tells the system to unzip the file before continuing, the x option tells it to extract the files from the tarball, the v option tells it to be verbose (write out the name of every file as it's being extracted, and the f option tells the tar command that we're extracting the file from a tarball file, and not from a tape. [root@server src]# tar -zxvf libpri-1.X.Y.tar.gz [root@server src]# tar -zxvf dahdi-linux-complete-2.X.Y+2.X.Y.tar.gz [root@server src]# tar -zxvf asterisk-1.8.X.Y.tar.gz You should now notice that a new sub-directory was created for each of the tarballs, each containing the extracted files from the corresponding tarball. We can now compile and install each of the components. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 91 Building and Installing DAHDI With Internet Access Without Internet Access Let's install DAHDI! On Linux, we will use the DAHDI-linux-complete tarball, which contains both the DAHDI Linux drivers as well as the DAHDI tools. Again, we're assuming that you've untarred the tarball in the /usr/local/src directory, and that you'll replace X and Y with the appropriate version numbers. LibPRI 1.4.13 and later source code depends on DAHDI include files. So, as a change from older versions, one must install DAHDI before installing libPRI. With Internet Access [root@server src]# cd dahdi-linux-complete-2.X.Y+2.X.Y [root@server dahdi-linux-complete-2.X.Y+2.X.Y]# make [root@server dahdi-linux-complete-2.X.Y+2.X.Y]# make install [root@server dahdi-linux-complete-2.X.Y+2.X.Y]# make config Without Internet Access When installing on a system without internet access, there are a few additional steps that are required to build DAHDI. The firmware files for the various VPM modules will need to be downloaded and extracted in the source directory. The file specific links provided below are the current versions as of this writing. Please check the link below for the full list of versions. http://downloads.digium.com/pub/telephony/firmware/releases/ On a system with internet access, download the following files: wget http://downloads.digium.com/pub/telephony/firmware/releases/dahdi-fw-hx8-2.06.tar.gz wget http://downloads.digium.com/pub/telephony/firmware/releases/dahdi-fw-oct6114-064-1.05.01.tar.gz wget http://downloads.digium.com/pub/telephony/firmware/releases/dahdi-fw-oct6114-128-1.05.01.tar.gz wget http://downloads.digium.com/pub/telephony/firmware/releases/dahdi-fw-vpmoct032-1.8.0.tar.gz wget http://downloads.digium.com/pub/telephony/firmware/releases/dahdi-fw-tc400m-MR6.12.tar.gz wget http://downloads.digium.com/pub/telephony/firmware/releases/dahdi-fwload-vpmadt032-1.25.0.tar.gz Now send these to the Asterisk system and store them in /usr/local/src/dahdi-linux-complete-2.X.Y+2.X.Y/linux/drivers/dahdi/firmware/ Now we can continue the installation on the Asterisk system using the steps below. [root@server src]# cd dahdi-linux-complete-2.X.Y+2.X.Y [root@server dahdi-linux-complete-2.X.Y+2.X.Y]# cd linux/drivers/dahdi/firmware [root@server firmware]# for tarball in $(ls dahdi-fw-*.tar.gz); do tar -zxf $tarball; done; [root@server firmware]# cd [root@server dahdi-linux-complete-2.X.Y+2.X.Y]# make [root@server dahdi-linux-complete-2.X.Y+2.X.Y]# make install [root@server dahdi-linux-complete-2.X.Y+2.X.Y]# make config Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 92 Building and Installing LibPRI Before you can build libpri, you'll need to Building and Installing DAHDI Having finished that, let's compile and install libpri. Again, we'll assume that you'll replace the letters X, Y, and Z with the actual version numbers from the tarballs you downloaded. [root@server src]# cd libpri-1.X.Y This command changes directories to the libpri source directory. [root@server libpri-1.X.Y]# make This command compiles the libpri source code into a system library. [root@server libpri-1.X.Y]# make install This command installs the libpri library into the proper system library directory Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 93 Checking Asterisk Requirements Now it's time to compile and install Asterisk. Let's change to the directory which contains the Asterisk source code. [root@server dahdi-linux-complete-2.X.Y+2.X.Y]# cd /usr/local/src/asterisk-1.8.X.Y Next, we'll run a command called ./configure, which will perform a number of checks on the operating system, and get the Asterisk code ready to compile on this particular server. [root@server asterisk-1.8.X.Y]# ./configure This will run for a couple of minutes, and warn you of any missing system libraries or other dependencies. If you have missing dependencies then you should install them now and then run configure again to make sure they are recognized. A helpful way to install most of the dependencies you need is to use the install_prereq script included in the contrib/scripts/ directory of your Asterisk source. It's quite straightforward to use, but may not work on all systems. Run the script with no arguments to see the usage help. Upon completion of ./configure, you should see a message that looks similar to the one shown below. (Obviously, your host CPU type may be different than the below.) .$$$$$$$$$$$$$$$=.. .$7$7.. .7$$7:. .$7$7.. .7$$7:. .$$:. ,$7.7 .$7. 7$$$$ .$$77 ..$$. $$$$$ .$$$7 ..7$ .?. $$$$$ .?. 7$$$. $.$. .$$$7. $$$$7 .7$$$. .$$$. .777. .$$$$$$77$$$77$$$$$7. $$$, $$$~ .7$$$$$$$$$$$$$7. .$$$. .$$7 .7$$$$$$$7: ?$$$. $$$ ?7$$$$$$$$$$I .$$$7 $$$ .7$$$$$$$$$$$$$$$$ :$$$. $$$ $$$$$$7$$$$$$$$$$$$ .$$$. $$$ $$$ 7$$$7 .$$$ .$$$. $$$$ $$$$7 .$$$. 7$$$7 7$$$$ 7$$$ $$$$$ $$$ $$$$7. $$ (TM) $$$$$$$. .7$$$$$$ $$ $$$$$$$$$$$$7$$$$$$$$$.$$$$$$ $$$$$$$$$$$$$$$$. configure: configure: configure: configure: configure: Package configured for:  OS type  : linux-gnu Host CPU : x86_64 build-cpu:vendor:os: x86_64 : unknown : linux-gnu : host-cpu:vendor:os: x86_64 : unknown : linux-gnu : Cached Data The ./configure command caches certain data to speed things up if it's invoked multiple times. To clear all the cached data, you can use the following command to completely clear out any cached data from the Asterisk build system. [root@server asterisk-1.8.X.Y]# make distclean Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 94 Using Menuselect to Select Asterisk Options The next step in the build process is to tell Asterisk which modules[docs:1] to compile and install, as well as set various compiler options. These settings are all controlled via a menu-driven system called menuselect. To access the menuselect system, type: [root@server asterisk-1.8.X.Y]# make menuselect Terminal Window Your terminal window size must be at least eighty characters wide and twenty-one lines high, or menuselect will not work. Instead, you'll get an error message stating Terminal must be at least 80 x 21. Asterisk 1.8+ Terminal must be at least 80 x 27. The menuselect menu should look like the screen-shot below. On the left-hand side, you have a list of categories, such as Applications, Channel Drivers, and PBX Modules. On the right-hand side, you'll see a list of modules that correspond with the select category. At the bottom of the screen you'll see two buttons. You can use the Tab key to cycle between the various sections, and press the Enter key to select or unselect a particular module. If you see [docs:] next to a module name, it signifies that the module has been selected. If you see *XXX next to a module name, it signifies that the select module cannot be built, as one of its dependencies is missing. In that case, you can look at the bottom of the screen for the line labeled Depends upon: for a description of the missing dependency. When you're first learning your way around Asterisk on a test system, you'll probably want to stick with the default settings in menuselect. If you're building a production system, however, you may not wish to build all of the various modules, and instead only build the modules that your system is using. Easier Debugging of Asterisk Crashes If you're finding that Asterisk is crashing on you, there's a setting in menuselect that will help provide additional information to the Asterisk developers. Go into menuselect, select the the Compiler Flags section (you'll need to scroll down in the left-hand list), and select the DONT_OPTIMIZE setting. Then rebuild Asterisk as shown below. While the Asterisk application will be slightly larger, it will provide additional debugging symbols in the event of a crash. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 95 We should also inform people that the sound prompts are selected in menuselect as well When you are finished selecting the modules and options you'd like in menuselect, press F12 to save and exit, or highlight the Save and Exit button and press enter. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 96 Building and Installing Asterisk Now we can compile and install Asterisk. To compile Asterisk, simply type make at the Linux command line. [root@server asterisk-1.8.X.Y]# make The compiling step will take several minutes, and you'll see the various file names scroll by as they are being compiled. Once Asterisk has finished compiling, you'll see a message that looks like: +--------- Asterisk Build Complete ---------+ + Asterisk has successfully been built, and + + can be installed by running: + + + + make install + +-------------------------------------------+ +--------- Asterisk Build Complete ---------+ As the message above suggests, our next step is to install the compiled Asterisk program and modules. To do this, use the make install command. [root@server asterisk-1.8.X.Y]# make install When finished, Asterisk will display the following warning: +---- Asterisk Installation Complete -------+ + + + YOU MUST READ THE SECURITY DOCUMENT + + + + Asterisk has successfully been installed. + + If you would like to install the sample + + configuration files (overwriting any + + existing config files), run: + + + + make samples + + + +-------------------------------------------+ +---- Asterisk Installation Complete -------+ Security Precautions As the message above suggests, we very strongly recommend that you read the security documentation before continuing with your Asterisk installation. Failure to read and follow the security documentation can leave your system vulnerable to a number of security issues, including toll fraud. If you installed Asterisk from a tarball (as shown above), the security information is located in a PDF file named asterisk.pdfin the tex/ sub-directory of the source code. If that file doesn't exist, please install the rubber application on your system, and then type: [root@server asterisk-1.8.X.Y]# make pdf Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 97 Installing Sample Files To install a set of sample configuration files for Asterisk, type: [root@server asterisk-1.8.X.Y]# make samples Any existing sample files which have been modified will be given a .old file extension. For example, if you had an existing file named extensions.conf, it would be renamed to extensions.conf.old and the sample dialplan would be installed as extensions.conf. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 98 Installing Initialization Scripts Now that you have Asterisk compiled and installed, the last step is to install the initialization script, or initscript. This script starts Asterisk when your server starts, and can be used to stop or restart Asterisk as well. To install the initscript, use the make config command. [root@server asterisk-1.8.X.Y]# make config As your Asterisk system runs, it will generate logfiles. It is recommended to install the logrotation script in order to compress and rotate those files, to save disk space and to make searching them or cataloguing them easier. To do this, use the make install-logrotate command. [root@server asterisk-1.8.X.Y]# make install-logrotate Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 99 Validating Your Installation Before continuing on, let's check a few things to make sure your system is in good working order. First, let's make sure the DAHDI drivers are loaded. You can use the lsmod under Linux to list all of the loaded kernel modules, and the grep command to filter the input and only show the modules that have dah di in their name. [root@server asterisk-1.8.X.Y]# lsmod | grep dahdi If the command returns nothing, then DAHDI has not been started. Start DAHDI by running: [root@server asterisk-1.8.X.Y]# /etc/init.d/dadhi start Different Methods for Starting Initscripts Many Linux distributions have different methods for starting initscripts. On most Red Hat based distributions (such as Red Hat Enterprise Linux, Fedora, and CentOS) you can run: [root@server asterisk-1.8.X.Y]# service dahdi start Distributions based on Debian (such as Ubuntu) have a similar command, though it's not commonly used: [root@server asterisk-1.8.X.Y]# invoke-rc.d dahdi start If you have DAHDI running, the output of lsmod | grep dahdi should look something like the output below. (The exact details may be different, depending on which DAHDI modules have been built, and so forth.) [root@server asterisk-1.8.X.Y]# lsmod | grep dahdi dahdi_dummy 4288 0 dahdi_transcode 7928 1 wctc4xxp dahdi_voicebus 40464 2 wctdm24xxp,wcte12xp dahdi 196544 12 dahdi_dummy,wctdm24xxp,wcte11xp,wct1xxp,wcte12xp,wct4xxp crc_ccitt 2096 1 dahdi Now that DAHDI is running, you can run dahdi_hardware to list any DAHDI-compatible devices in your system. You can also run the dahdi_tool utility to show the various DAHDI-compatible devices, and their current state. To check if Asterisk is running, you can use the Asterisk initscript. [root@server asterisk-1.8.X.Y]# /etc/init.d/asterisk status asterisk is stopped To start Asterisk, we'll use the initscript again, this time giving it the start action: [root@server asterisk-1.8.X.Y]# /etc/init.d/asterisk start Starting asterisk: When Asterisk starts, it runs as a background service (or daemon), so you typically won't see any response on the command line. We can check the status of Asterisk and see that it's running using the command below. (The process identifier, or pid, will obviously be different on your system.) [root@server asterisk-1.8.X.Y]# /etc/init.d/asterisk status asterisk (pid 32117) is running... And there you have it! You've compiled and installed Asterisk, DAHDI, and libpri from source code. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 100 Getting Started with Asterisk In this section, we'll show you how to get started with Asterisk, and how to get around on the Asterisk command-line interface (commonly abbreviated as CLI). We'll also show you how to troubleshoot common problems that you might encounter when first learning Asterisk Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 101 Connecting to the CLI First, let's show you how to connect to the Asterisk command-line interface. As you should recall from the installation, Asterisk typically runs in the background as a service or daemon. If the Asterisk service is already running, type the command below to connect to its command-line interface. [root@server ~]# asterisk -r The -r parameter tells the system that you want to re-connect to the Asterisk service. If the reconnection is successful, you'll see something like this: [root@server ~]# asterisk -r Asterisk version, Copyright (C) 1999 - 2010 Digium, Inc. and others. Created by Mark Spencer Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details. This is free software, with components licensed under the GNU General Public License version 2 and other licenses; you are welcome to redistribute it under certain conditions. Type 'core show license' for details. ========================================================================= Connected to Asterisk version currently running on server (pid = 11187) server*CLI> Notice the *CLI> text? That's your Asterisk command-line prompt. All of the Asterisk CLI commands take the form of module action parameters.... For example, type core show uptime to see how long Asterisk has been running. server*CLI> core show uptime System uptime: 1 hour, 34 minutes, 17 seconds Last reload: 1 hour, 34 minutes, 17 seconds You can use the built-in help to get more information about the various commands. Simply type core show help at the Asterisk prompt for a full list of commands, or core show help command for help on a particular command. If you'd like to exit the Asterisk console and return to your shell, just use the quit command from the CLI. Such as: server*CLI> quit Executing Command Outside Of CLI You can execute an Asterisk command from outside the CLI: $ asterisk -rx "core reload" $ asterisk -rx "core show help" | grep -i "sip" Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 102 Stopping and Restarting Asterisk There are four common commands related to stopping the Asterisk service. They are: 1. core stop now - This command stops the Asterisk service immediately, ending any calls in progress. 2. core stop gracefully - This command prevents new calls from starting up in Asterisk, but allows calls in progress to continue. When all the calls have finished, Asterisk stops. 3. core stop when convenient - This command waits until Asterisk has no calls in progress, and then it stops the service. It does not prevent new calls from entering the system. There are three related commands for restarting Asterisk as well. 1. core restart now - This command restarts the Asterisk service immediately, ending any calls in progress. 2. core restart gracefully - This command prevents new calls from starting up in Asterisk, but allows calls in progress to continue. When all the calls have finished, Asterisk restarts. 3. core restart when convenient - This command waits until Asterisk has no calls in progress, and then it restarts the service. It does not prevent new calls from entering the system. There is also a command if you change your mind. core abort shutdown - This command aborts a shutdown or restart which was previously initiated with the gracefully or when convenient options. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 103 Changing the Verbose and Debug Levels Asterisk has two different classes of messages that appear in the command-line interface. The first class is called verbose messages. Verbose messages give information about the calls on the system, as well as notices, warnings, and errors. Verbose messages are intended for Asterisk administrators to be able to better manage their systems. Asterisk allows you to control the verbosity level of the command-line interface. At a verbosity level of zero, you'll receive minimal information about calls on your system. As you increase the verbosity level, you'll see more and more information about the calls. For example, if you set the verbosity level to three or higher, you'll see each step a call takes as it makes its way through the dialplan. There are very few messages that only appear at verbosity levels higher than three. To change the verbosity level, use the CLI command core set verbose, as shown below: server*CLI> core set verbose 3 Verbosity was 0 and is now 3 You can also increase (but not decrease) the verbosity level when you connect to the Asterisk CLI from the Linux prompt, by using one or more -v paramet ers to the asterisk application. For example, this would connect to the Asterisk CLI and set the verbosity to three (if it wasn't already three or higher), because we added three -v parameters: [root@server ~]# asterisk -vvvr The second class of system messages is known as debug messages. These messages are intended for Asterisk developers, to give information about what's happening in the Asterisk program itself. They're often used by developers when trying to track down problems in the code, or to understand why Asterisk is behaving in a certain manner. To change the debugging level, use the CLI command core set debug, as shown below: server*CLI> core set debug 4 Core debug was 0 and is now 4 You can also increase (but not decrease) the debugging level when you connect to the Asterisk CLI from the Linux prompt. Simply add one or more -d para meters to the asterisk application. [root@server ~]# asterisk \-ddddr Verbose and Debug Levels Please note that the verbose and debug levels are global settings, and apply to all of Asterisk, not just your command-line interface. We recommend that you set your verbosity level to three while learning Asterisk, so that you can get a feel for what is happening as calls are processed. On a busy production system, however, you'll want to set the verbosity level lower. We also recommend that you use debug messages sparingly, as they tend to be quite verbose and can affect call volume on busy systems. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 104 Simple CLI Tricks There are a couple of tricks that will help you on the Asterisk command-line interface. The most popular is tab completion. If you type the beginning of a command and press the Tab key, Asterisk will attempt to complete the name of the command for you, or show you the possible commands that start with the letters you have typed. For example, type co and then press the Tab key on your keyboard. server*CLI> co[Tab] config core server*CLI> co Now press the r key, and press tab again. This time Asterisk completes the word for you, as core is the only command that begins with cor. This trick also works with sub-commands. For example, type core show and press tab. (You may have to press tab twice, if you didn't put a space after the word show.) Asterisk will show you all the sub-commands that start with core show. server*CLI> core show [Tab] application applications channels channeltype codecs config functions help image license switches sysinfo translation uptime server*CLI> core show calls channeltypes file hint profile taskprocessors version channel codec function hints settings threads warranty Another trick you can use on the CLI is to cycle through your previous commands. Asterisk stores a history of the commands you type and you can press the up arrow key to cycle through the history. If you type an exclamation mark at the Asterisk CLI, you will get a Linux shell. When you exit the Linux shell (by typing exit or pressing Ctrl+D), you return to the Asterisk CLI. You can also type an exclamation mark and a Linux command, and the output of that command will be shown to you, and then you'll be returned to the Asterisk CLI. server*CLI> !whoami root server*CLI> As you can see, there's a wealth of information available from the Asterisk command-line interface, and we've only scratched the surface. In later sections, we'll go into more details about how to use the command-line interface for other purposes. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 105 Troubleshooting If you're able to get the command-line examples above working, feel free to skip this section. Otherwise, let's look at troubleshooting connections to the Asterisk CLI. The most common problem that people encounter when learning the Asterisk command-line interface is that sometimes they're not able to connect to the Asterisk service running in the background. For example, let's say that Fred starts the Asterisk service, but then isn't able to connect to it with the CLI: [root@server ~]# service asterisk start Starting asterisk: [ OK ] [root@server ~]# asterisk -r Asterisk version, Copyright (C) 1999 - 2010 Digium, Inc. and others. Created by Mark Spencer ========================================================================= Unable to connect to remote asterisk (does /var/run/asterisk/asterisk.ctl exist?) What does this mean? It most likely means that Asterisk did not remain running between the time that the service was started and the time Fred tried to connect to the CLI (even if it was only a matter of a few seconds.) This could be caused by a variety of things, but the most common is a broken configuration file. To diagnose Asterisk start-up problems, we'll start Asterisk in a special mode, known as console mode. In this mode, Asterisk does not run as a background service or daemon, but instead runs directly in the console. To start Asterisk in console mode, pass the -c parameter to the asterisk applicatio n. In this case, we also want to turn up the verbosity, so we can see any error messages that might indicate why Asterisk is unable to start. [root@server ~]# asterisk -vvvc Asterisk version, Copyright (C) 1999 - 2010 Digium, Inc. and others. Created by Mark Spencer Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details. This is free software, with components licensed under the GNU General Public License version 2 and other licenses; you are welcome to redistribute it under certain conditions. Type 'core show license' for details. ========================================================================= == Parsing '/etc/asterisk/asterisk.conf': == Found == Parsing '/etc/asterisk/extconfig.conf': == Found == Parsing '/etc/asterisk/logger.conf': == Found == Parsing '/etc/asterisk/asterisk.conf': == Found Asterisk Dynamic Loader Starting: == Parsing '/etc/asterisk/modules.conf': == Found ... Carefully look for any errors or warnings that are printed to the CLI, and you should have enough information to solve whatever problem is keeping Asterisk from starting up. Running Asterisk in Console Mode We don't recommend you use Asterisk in console mode on a production system, but simply use it for debugging, especially when debugging start-up problems. On production systems, run Asterisk as a background service. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 106 Asterisk Architecture From an architectural standpoint, Asterisk is made up of many different modules. This modularity gives you an almost unlimited amount of flexibility in the design of an Asterisk-based system. As an Asterisk administrator, you have the choice on which modules to load. Each module that you loads provides different capabilities to the system. For example, one module might allow your Asterisk system to communicate with analog phone lines, while another might add call reporting capabilities. In this section, we'll discuss the various types of modules and the capabilities they provide. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 107 Types of Asterisk Modules There are many different types of modules, many of which are shown in the diagram above. Channel Drivers At the top of the diagram, we show channel drivers. Channel drivers communicate with devices outside of Asterisk, and translate that particular signaling or protocol to the core. Dialplan Applications Applications provide call functionality to the system. An application might answer a call, play a sound prompt, hang up a call, and so forth. Dialplan Functions Functions are used to retrieve or set various settings on a call. A function might be used to set the Caller ID on an outbound call, for example. Resources As the name suggests, resources provide resources to Asterisk. Common examples of resources include music on hold and call parking. CODECs A CODEC (which is an acronym for COder/DECoder) is a module for encoding or decoding audio or video. Typically codecs are used to encode media so that it takes less bandwidth. File Format Drivers File format drivers are used to save media to disk in a particular file format, and to convert those files back to media streams on the network. Call Detail Record (CDR) Drivers CDR drivers write call logs to a disk or to a database. Call Event Log (CEL) Drivers Call event logs are similar to call detail records, but record more detail about what happened inside of Asterisk during a particular call. Bridge Drivers Bridge drivers are used by the bridging architecture in Asterisk, and provide various methods of bridging call media between participants in a call. Now let's go into more detail on each of the module types. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 108 Channel Driver Modules All calls from the outside come through a channel driver before reaching the core, and all outbound calls go through a channel driver on their way to the external device. The SIP channel driver, for example, communicates with external devices using the SIP protocol. It translates the SIP signaling into the core. This means that the core of Asterisk is signaling agnostic. Therefore, Asterisk isn't just a SIP PBX, it's a multi-protocol PBX. For more information on the various channel drivers, see Section 400. Channel Drivers and External Connectivity. All channel drivers have a file name that look like chan_xxxxx.so, such as chan_sip.so or chan_dahdi.so. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 109 Dialplan Application Modules The application modules provide call functionality to the system. These applications are then scripted sequentially in the dialplan. For example, a call might come into Asterisk dialplan, which might use one application to answer the call, another to play back a sound prompt from disk, and a third application to allow the caller to leave voice mail in a particular mailbox. For more information on dialplan applications, see Dialplan Fundamentals. All application modules have file names that looks like app_xxxxx.so, such as app_voicemail.so. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 110 Dialplan Function Modules Dialplan functions are somewhat similar to dialplan applications, but instead of doing work on a particular channel or call, they simply retrieve or set a particular setting on a channel, or perform text manipulation. For example, a dialplan function might retrieve the Caller ID information from an incoming call, filter some text, or set a timeout for caller input. For more information on dialplan functions, see PBX Features. All dialplan application modules have file names that looks like func_xxxxx.so, such as func_callerid.so. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 111 Resource Modules Resources provide functionality to Asterisk that may be called upon at any time during a call, even while another application is running on the channel. Resources are typically used of asynchronous events such as playing hold music when a call gets placed on hold, or performing call parking. Resource modules have file names that looks like res_xxxxx.so, such as res_musiconhold.so. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 112 Codec Modules CODEC modules have file names that look like codec_xxxxx.so, such as codec_alaw.so and codec_ulaw.so. CODECs represent mathematical algorithms for encoding (compressing) and decoding (decompression) media streams. Asterisk uses CODEC modules to both send and recieve media (audio and video). Asterisk also uses CODEC modules to convert (or transcode) media streams between different formats. CODEC modules have file names that look like codec_xxxxx.so, such as codec_alaw.so and codec_ulaw.so. Asterisk is provided with CODEC modules for the following media types: ADPCM, 32kbit/s G.711 alaw, 64kbit/s G.711 ulaw, 64kbit/s G.722, 64kbit/s G.726, 32kbit/s GSM, 13kbit/s LPC-10, 2.4kbit/s If the Speex (www.speex.org) development libraries are detected on your system when Asterisk is built, a CODEC module for Speex will also be installed. If the iLBC (www.ilbcfreeware.org) development libraries are detected on your system when Asterisk is built, a CODEC module for iLBC will also be installed. Support for the patent-encumbered G.729A or G.723.1 CODECs is provided by Digium on a commercial basis through both software and hardware products. For more information about purchasing licenses or hardware to use the G.729A or G.723.1 CODECs with Asterisk, please see Digium's website. Support for Polycom's patent-encumbered but free G.722.1 Siren7 and G.722.1C Siren14 CODECs, or for Skype's SILK CODEC, can be enabled in Asterisk by downloading the binary CODEC modules from Digium's website. For more detailed information on CODECs, see CODECs. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 113 File Format Drivers Add a list of the file formats that Asterisk supports, then point them at the module in section 400 that goes into more detail? Asterisk uses file format modules to take media (such as audio and video) from the network and save them on disk, or retrieve said files from disk and convert them back to a media stream. While often related to CODECs, there may be more than one available on-disk format for a particular CODEC. File format modules have file names that look like format_xxxxx.so, such as format_wav.so and format_jpeg.so. Add a list of the file formats that Asterisk supports, then point them at the module in section 400 that goes into more detail? Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 114 Call Detail Record (CDR) Drivers CDR modules are used to store call detail records in a variety of formats. Popular storage mechanisms include comma-separated value (CSV) files, as well as relational databases such as PostgreSQL. Call detail records typically contain one record per call, and give details such as who made the call, who answered the call, the amount of time spent on the call, and so forth. For more information on call detail records, see Section 370. Call Detail Records. Call detail record modules have file names that look like cdr_xxxxx.so, such as cdr_csv.so and cdr_pgsql.so. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 115 Call Event Log (CEL) Driver Modules Call Event Logs record the various actions that happen on a call. As such, they are typically more detailed that call detail records. For example, a call event log might show that Alice called Bob, that Bob's phone rang for twenty seconds, then Bob's mobile phone rang for fifteen seconds, the call then went to Bob's voice mail, where Alice left a twenty-five second voicemail and hung up the call. The system also allows for custom events to be logged as well. For more information about Call Event Logging, see Call Event Logging. Call event logging modules have file names that look like cel_xxxxx.so, such as cel_custom.so and cel_adaptive_odbc.so. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 116 Bridging Modules Beginning in Asterisk 1.6.2, Asterisk introduced a new method for bridging calls together. It relies on various bridging modules to control how the media streams should be mixed for the participants on a call. The new bridging methods are designed to be more flexible and more efficient than earlier methods. Bridging modules have file names that look like bridge_xxxxx.so, such as bridge_simple.so and bridge_multiplexed.so. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 117 Call Flow and Bridging Model Now that you know about the various modules that Asterisk uses, let's talk about the ways that calls flow through an Asterisk system. To explain this clearly, let's say that Alice wants to talk to Bob, and they both have SIP phones connected to their Asterisk system. Let's see what happens! Should we add a graphic to help explain the call flow model? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Alice dials extension 6002, which is Bob's extension on the Asterisk system. A SIP message goes from Alice's phone to the SIP channel driver in Asterisk The SIP channel driver authenticates the call. If Alice's phone does not provide the proper credentials, Asterisk rejects the call. At this point, we have Alice's phone communicating with Asterisk. Now the call goes from the SIP channel driver into the core of Asterisk. Asterisk looks for a set of instructions to follow for extension 6002 in the dialplan. Extension 6002 in the dialplan tells Asterisk to call Bob's phone Asterisk makes a call out through the SIP channel driver to Bob's phone. Bob answers his phone. Now we have two independent calls on the Asterisk system: one from Alice, and to Bob. Asterisk now bridges the audio between these two calls (known as channels in Asterisk parlance). When one channel hangs up, Asterisk signals the other channel to hang up. And there we have it! We've shown how calls flow from external devices, through the channel drivers to the core of Asterisk, and back out through the channel drivers to external devices. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 118 Asterisk Architecture, The Big Picture Before we dive too far into the various types of modules, let's first take a step back and look at the overall architecture of Asterisk. Asterisk Architecture We need to add CEL and Bridge modules to this picture, and take CLI and Manager out for now The heart of any Asterisk system is the core. The PBX core is the essential component that takes care of bridging calls. The core also takes care of other items like reading the configuration files and loading the other modules. We'll talk more about the core below, but for now just remember that all the other modules connect to it. From a logistical standpoint, these modules are typically files with a .so file extension, which live in the Asterisk modules directory (which is typically /usr/li b/asterisk/modules). When Asterisk starts up, it loads these files and adds their functionality to the system. A Plethora of Modules Take just a minute and go look at the Asterisk modules directory on your system. You should find a wide variety of modules. A typical Asterisk system has over one hundred fifty different modules! The core also contains the dialplan, which is the logic of any Asterisk system. The dialplan contains a list of instructions that Asterisk should follow to know how to handle incoming and outgoing calls on the system. Asterisk modules which are part of the core have a file name that look like pbx_xxxxx.so. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 119 Audiohooks Overview Certain applications and functions are capable of attaching what is known as an audiohook to a channel. In order to understand what this means and how to handle these applications and functions, it is useful to understand a little of the architecture involved with attaching them. Introduction - A Simple Audiohook In this simple example, a SIP phone has dialed into Asterisk and its channel has invoked a function (pitch_shift) which has been set to cause all audio sent and received to have its pitch shifted higher (i.e. if the audio is voice, the voices will sound squeaky sort of like obnoxious cartoon chipmunks). The following dialplan provides a more concrete usage: exten => 1,1,Answer() exten => 1,n,Set(PITCH_SHIFT(both)=higher) exten => 1,n,Voicemail(501) When a phone calls this extension, it will be greeted by a higher pitched version of the voicemail prompt and then the speaker will leave a message for 501. The sound going from the phone to voicemail will also be higher pitched than what was actually said by the person who left the message. Right now a serious minded Asterisk user reading this example might think something along the lines of 'So what, I don't have any use for making people using my phone system sound like squirrels." However, audiohooks provide a great deal of the functionality for other applications within Asterisk including some features that are very business minded (listening in on channels, recording phone calls, and even less spy-guy type things like adjusting volume on the fly) It's important to note that audiohooks are bound to the channel that they were invoked on. They don't apply to a call (a call is actually a somewhat nebulous concept in general anyway) and so one shouldn't expect audiohooks to follow other channels around just because audio that those channels are involved with touches the hook. If the channel that created the audiohook ceases to be involved with an audio stream, the audiohook will also no longer be involved with that audio stream. Attended Transfers and AUDIOHOOK_INHERIT Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 120 exten => 1,1,Answer() exten => 1,n,MixMonitor(training_recording.wav) exten => 1,n,Queue(techsupport) Imagine the following scenario. An outside line calls into an Asterisk system to enter a tech support queue. When the call starts this user hears something along the lines of "Thank you for calling, all calls will be recorded for training purposes", so naturally MixMonitor will be used to record the call. The first available agent answers the call and can't quite seem to provide a working solution to the customer's problem, so he attempts to perform an attended transfer to someone with more expertise on the issue. The user gets transfered, and the rest of the call goes smoothly, but... ah nuts. The recording stopped for some reason when the agent transferred the customer to the other user. And why didn't this happen when he blind transferred a customer the other day? The reason MixMonitor stopped is because the channel that owned it died. An Asterisk admin might think something like "That's not true, the mixmonitor was put on the customer channel and its still there, I can still see it's name is the same and everything." and it's true that it seems that way, but attended transfers in particular cause what's known as a channel masquerade. Yes, its name and everything else about it seems like the same channel, but in reality the customer's channel has been swapped for the agent's channel and died since the agent hung up. The audiohook went with it. Under normal circumstances, administrators don't need to think about masquerades at all, but this is one of the rare instances where it gets in the way of desired behavior. This doesn't affect blind transfers because they don't start the new dialog by having the person who initiated the transfer bridging to the end recipient. Working around this problem is pretty easy though. Audiohooks are not swapped by default when a masquerade occurs, unlike most of the relevant data on the channel. This can be changed on a case by case basis though with the AUDIOHOOK_INHERIT dialplan function. Using AUDIOHOOK_INHERT only requires that AUDIOHOOK_INHERIT(source)=yes is set where source is the name given for the source of the audiohook. For more information on the sources available, see the description of the source argument in the documentation for AUDIOHOOK_INHERIT. So to fix the above example so that mixmonitor continues to record after the attended transfer, only one extra line is needed. exten exten exten exten => => => => 1,1,Answer() 1,n,MixMonitor(training_recording.wav) 1,n,Set(AUDIOHOOK_INHERIT(MixMonitor)=yes) 1,n,Queue(techsupport) Below is an illustrated example of how the masquerade process impacts an audiohook (in the case of the example, PITCH_SHIFT) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 121 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 122 Inheritance of audiohooks can be turned off in the same way by setting AUDIOHOOK_INHERIT(source)=no. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 123 Audiohook Sources Audiohooks have a source name and can come from a number of sources. An up to date list of possible sources should always be available from the documentation for AUDIOHOOK_INHERIT. Chanspy - from app_chanspy MixMonitor - app_mixmonitor.c Volume - func_volume.c Mute - res_mutestream.c Speex - func_speex.c pitch_shift - func_pitchshift.c JACK_HOOK - app_jack.c Limitations for transferring Audiohooks Even with audiohook inheritance set, the MixMonitor is still bound to the channel that invoked it. The only difference in this case is that with this option set, the audiohook won't be left on the discarded channel through the masquerade. This option doesn't enable a channel running mixmonitor to transfer the MixMonitor to another channel or anything like that. The dialog below illustrates why. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 124 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 125 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 126 Asterisk on (Open)Solaris Asterisk on Solaris 10 and OpenSolaris On this page Asterisk on Solaris 10 and OpenSolaris Digium's Support Status Build Notes Prerequisites LDAP dependencies Makefile layouts FAX support with SpanDSP Gotchas Runtime issues Build issues Digium's Support Status According to the README file from 1.6.2: "Asterisk has also been 'ported' and reportedly runs properly on other operating systems as well, including Sun Solaris, Apple's Mac OS X, Cygwin, and the BSD variants." Digium's developers have also been doing a good job of addressing build and run-time issues encountered with Asterisk on Solaris. Build Notes Prerequisites The following packages are recommend for building Asterisk 1.6 and later on OpenSolaris: SUNWlibm (math library) gcc-dev (compiler and several dependencies) SUNWflexlex (GNU flex) SUNWggrp (GNU grep) SUNWgsed (GNU sed) SUNWdoxygen (optional; needed for "make progdocs") SUNWopenldap (optional; needed for res_config_ldap; see below) SUNWgnu-coreutils (optional; provides GNU install; see below) Caution: installing SUNW gnu packages will change the default application run when the user types 'sed' and 'grep' from /usr/bin/sed to /usr/gnu/bin/sed. Just be aware of this change, as there are differences between the Sun and GNU versions of these utilities. LDAP dependencies Because OpenSolaris ships by default with Sun's LDAP libraries, you must install the SUNWopenldap package to provide OpenLDAP libraries. Because of namespace conflicts, the standard LDAP detection will not work. There are two possible solutions: 1. Port res_config_ldap to use only the RFC-specified API. This should allow it to link against Sun's LDAP libraries. The problem is centered around the use of the OpenLDAP-specific ldap_initialize() call. 2. Change the detection routines in configure to use OpenSolaris' layout of OpenLDAP. This seems doubtful simply because the filesystem layout of SUNWopenldap is so non-standard. Despite the above two possibilities, there is a workaround to make Asterisk compile with res_config_ldap. Modify the "configure" script, changing all instances of "-lldap" to "-lldap-2.4". At the time of this writing there are only 4 instances. This alone will make configure properly detect LDAP availability. But it will not compile. When running make, specify the use of the OpenLDAP headers like this: "make LDAP_INCLUDE=-I/usr/include/openldap" Makefile layouts Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 127 This has been fixed in Asterisk 1.8 and is no longer an issue. In Asterisk 1.6 the Makefile overrides any usage of --prefix. I suspect the assumptions are from back before configure provided the ability to set the installation prefix. Regardless, if you are building on OpenSolaris, be aware of this behavior of the Makefile! If you want to alter the install locations you will need to hand-edit the Makefile. Search for the string "SunOS" to find the following section: # Define standard directories for various platforms # These apply if they are not redefined in asterisk.conf ifeq ($(OSARCH),SunOS) ASTETCDIR=/etc/asterisk ASTLIBDIR=/opt/asterisk/lib ASTVARLIBDIR=/var/opt/asterisk ASTDBDIR=$(ASTVARLIBDIR) ASTKEYDIR=$(ASTVARLIBDIR) ASTSPOOLDIR=/var/spool/asterisk ASTLOGDIR=/var/log/asterisk ASTHEADERDIR=/opt/asterisk/include/asterisk ASTBINDIR=/opt/asterisk/bin ASTSBINDIR=/opt/asterisk/sbin ASTVARRUNDIR=/var/run/asterisk ASTMANDIR=/opt/asterisk/man else Note that, despite the comment, these definitions have build-time and run-time implications. Make sure you make these changes BEFORE you build! FAX support with SpanDSP I have been able to get this to work reliably, including T.38 FAX over SIP. If you are running Asterisk 1.6 note Ticket 16342 if you do not install SpanDSP to the default locations (/usr/include and /usr/lib). There is one build issue with SpanDSP that I need to document (FIXME) Gotchas Runtime issues WAV and WAV49 files are not written correctly (see Ticket 16610) 32-bit binaries on Solaris are limited to 255 file descriptors by default. (see http://developers.sun.com/solaris/articles/stdio_256.html) Build issues bootstrap.sh does not correctly detect OpenSolaris build tools (see Ticket 16341) Console documentation is not properly loaded at startup (see Ticket 16688) Solaris sed does not properly create AEL parser files (see Ticket 16696; workaround is to install GNU sed with SUNWgsed) Asterisk's provided install script, install-sh, is not properly referenced in the makeopts file that is generated during the build. One workaround is to install GNU install from the SUNWgnu-coreutils package. (See Ticket 16781) Finally, Solaris memory allocation seems far more sensitive than Linux. This has resulted in the discovery of several previously unknown bugs related to uninitialized variables that Linux handled silently. Note that this means, until these bugs are found and fixed, you may get segfaults. At the time of this writing I have had a server up and running reasonably stable. However, there are large sections of Asterisk's codebase I do not use and likely contain more of these uninitialized variable problems and associated potential segfaults. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 128 Configuration and Operation Here is the top-level page for all of the Asterisk Reference Information, formerly found in the doc/ and doc/tex subdirectories of the Asterisk source. It's been there all along, but now it's here, in an easy to view format (no need to install 800MB of dependancies in Debian just to convert .tex into PDF), that's also searchable. Hoo-ray! Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 129 Asterisk Calendaring The Asterisk Calendaring API aims to be a generic interface for integrating Asterisk with various calendaring technologies. The goal is to be able to support reading and writing of calendar events as well as allowing notification of pending events through the Asterisk dialplan. There are three calendaring modules that ship with Asterisk that provide support for iCalendar, CalDAV, and Microsoft Exchange Server calendars. All three modules support event notification. Both CalDAV and Exchange support reading and writing calendars, while iCalendar is a read-only format. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 130 Configuring Asterisk Calendaring All asterisk calendaring modules are configured through calender.conf. Each calendar module can define its own set of required parameters in addition to the parameters available to all calendar types. An effort has been made to keep all options the same in all calendaring modules, but some options will diverge over time as features are added to each module. An example calendar.conf might look like: [calendar_joe] type = ical url = https://example.com/home/jdoe/Calendar user = jdoe secret = mysecret refresh = 15 timeframe = 600 autoreminder = 10 channel = SIP/joe context = calendar_event_notify extension = s waittime = 30 Module-independent settings The settings related to calendar event notification are handled by the core calendaring API. These settings are: autoreminder - This allows the overriding of any alarms that may or may not be set for a calendar event. It is specified in minutes. refresh - How often to refresh the calendar data; specified in minutes. timeframe - How far into the future each calendar refresh should look. This is the amount of data that will be visible to queries from the dialplan. This setting should always be greater than or equal to the refresh setting or events may be missed. It is specified in minutes. channel - The channel that should be used for making the notification attempt. waittime - How long to wait, in seconds, for the channel to answer a notification attempt. There are two ways to specify how to handle a notification. One option is providing a context and extension, while the other is providing an application and the arguments to that application. One (and only one) of these options should be provided. context - The context of the extension to connect to the notification channel extension - The extension to connect to the notification. Note that the priority will always be 1. app - The dialplan application to execute upon the answer of a notification appdata - The data to pass to the notification dialplan application Module-dependent settings Connection-related options are specific to each module. Currently, all modules take a url, user, and secret for configuration and no other module-specific settings have been implemented. At this time, no support for HTTP redirects has been implemented, so it is important to specify the correct URL-paying attention to any trailing slashes that may be necessary. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 131 Calendaring Dialplan Functions Read functions The simplest dialplan query is the CALENDAR_BUSY query. It takes a single option, the name of the calendar defined, and returns "1" for busy (including tentatively busy) and "0" for not busy. For more information about a calendar event, a combination of CALENDAR_QUERY and CALENDAR_QUERY_RESULT is used. CALENDAR_QUERY takes the calendar name and optionally a start and end time in "unix time" (seconds from unix epoch). It returns an id that can be passed to CALENDAR_QUERY_RESULT along with a field name to return the data in that field. If multiple events are returned in the query, the number of the event in the list can be specified as well. The available fields to return are: summary - A short summary of the event description - The full description of the event organizer - Who organized the event location - Where the event is located calendar - The name of the calendar from calendar.conf uid - The unique identifier associated with the event start - The start of the event in seconds since Unix epoch end - The end of the event in seconds since Unix epoch busystate - The busy state 0=Free, 1=Tentative, 2=Busy attendees - A comma separated list of attendees as stored in the event and may include prefixes such as "mailto:". When an event notification is sent to the dial plan, the CALENDAR_EVENT function may be used to return the information about the event that is causing the notification. The fields that can be returned are the same as those from CALENDAR_QUERY_RESULT. Write functions To write an event to a calendar, the CALENDAR_WRITE function is used. This function takes a calendar name and also uses the same fields as CALENDAR_QUERY_RESULT. As a write function, it takes a set of comma-separated values that are in the same order as the specified fields. For example: CALENDAR_WRITE(mycalendar,summary,organizer,start,end,busystate)= "My event","mailto:jdoe@example.com",228383580,228383640,1) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 132 Calendaring Dialplan Examples Office hours A common business PBX scenario is would be executing dialplan logic based on when the business is open and the phones staffed. If the business is closed for holidays, it is sometimes desirable to play a message to the caller stating why the business is closed. The standard way to do this in asterisk has been doing a series of GotoIfTime statements or time-based include statements. Either way can be tedious and requires someone with access to edit asterisk config files. With calendaring, the adminstrator only needs to set up a calendar that contains the various holidays or even recurring events specifying the office hours. A custom greeting filename could even be contained in the description field for playback. For example: [incoming] exten => 5555551212,1,Answer same => n,GotoIf(${CALENDAR_BUSY(officehours)}?closed:attendant,s,1) same => n(closed),Set(id=${CALENDAR_QUERY(office,${EPOCH},${EPOCH})}) same => n,Set(soundfile=${CALENDAR_QUERY_RESULT(${id},description)}) same => n,Playback($[${ISNULL(soundfile)} ? generic-closed :: ${soundfile}]) same => n,Hangup Meeting reminders One useful application of Asterisk Calendaring is the ability to execute dialplan logic based on an event notification. Most calendaring technologies allow a user to set an alarm for an event. If these alarms are set on a calendar that Asterisk is monitoring and the calendar is set up for event notification via calendar.conf, then Asterisk will execute notify the specified channel at the time of the alarm. If an overrided notification time is set with the autoreminder setting, then the notification would happen at that time instead. The following example demonstrates the set up for a simple event notification that plays back a generic message followed by the time of the upcoming meeting. calendar.conf. [calendar_joe] type = ical url = https://example.com/home/jdoe/Calendar user = jdoe secret = mysecret refresh = 15 timeframe = 600 autoreminder = 10 channel = SIP/joe context = calendar_event_notify extension = s waittime = 30 extensions.conf : [calendar_event_notify] exten => s,1,Answer same => n,Playback(you-have-a-meeting-at) same => n,SayUnixTime(${CALENDAR_EVENT(start)}) same => n,Hangup Writing an event Both CalDAV and Exchange calendar servers support creating new events. The following example demonstrates writing a log of a call to a calendar. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 133 [incoming] exten => 6000,1,Set(start=${EPOCH}) exten => 6000,n,Dial(SIP/joe) exten => h,1,Set(end=${EPOCH}) exten => h,n,Set(CALENDAR_WRITE(calendar_joe,summary,start,end)=Call from ${CALLERID(all)},${start},${end}) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 134 Asterisk Channel Drivers All about Asterisk and its Channel Drivers Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 135 Inter-Asterisk eXchange protocol, version 2 (IAX2) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 136 Why IAX2? The first question most people are thinking at this point is "Why do you need another VoIP protocol? Why didn't you just use SIP or H.323?" Well, the answer is a fairly complicated one, but in a nutshell it's like this... Asterisk is intended as a very flexible and powerful communications tool. As such, the primary feature we need from a VoIP protocol is the ability to meet our own goals with Asterisk, and one with enough flexibility that we could use it as a kind of laboratory for inventing and implementing new concepts in the field. Neither H.323 or SIP fit the roles we needed, so we developed our own protocol, which, while not standards based, provides a number of advantages over both SIP and H.323, some of which are: Interoperability with NAT/PAT/Masquerade firewalls - IAX2 seamlessly interoperates through all sorts of NAT and PAT and other firewalls, including the ability to place and receive calls, and transfer calls to other stations. High performance, low overhead protocol – When running on low-bandwidth connections, or when running large numbers of calls, optimized bandwidth utilization is imperative. IAX2 uses only 4 bytes of overhead. Internationalization support – IAX2 transmits language information, so that remote PBX content can be delivered in the native language of the calling party. Remote dialplan polling – IAX2 allows a PBX or IP phone to poll the availability of a number from a remote server. This allows PBX dialplans to be centralized. Flexible authentication – IAX2 supports cleartext, MD5, and RSA authentication, providing flexible security models for outgoing calls and registration services. Multimedia protocol – IAX2 supports the transmission of voice, video, images, text, HTML, DTMF, and URL's. Voice menus can be presented in both audibly and visually. Call statistic gathering – IAX2 gathers statistics about network performance (including latency and jitter), as well as providing end-to-end latency measurement. Call parameter communication – Caller*ID, requested extension, requested context, etc. are all communicated through the call. Single socket design – IAX2's single socket design allows up to 32768 calls to be multiplexed. While we value the importance of standards based (i.e. SIP) call handling, hopefully this will provide a reasonable explanation of why we developed IAX2 rather than starting with SIP. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 137 Introduction to IAX2 This section is intended as an introduction to the Inter-Asterisk eXchange v2 (or simply IAX2) protocol. It provides both a theoretical background and practical information on its use. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 138 IAX2 Configuration For examples of a configuration, please see the iax.conf.sample in the /configs directory of your source code distribution. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 139 IAX2 Jitterbuffer The new jitterbuffer You must add jitterbuffer=yes to either the [general] part of iax.conf, or to a peer or a user. (just like the old jitterbuffer). Also, you can set max jitterbuffer=n, which puts a hard-limit on the size of the jitterbuffer of "n milliseconds". It is not necessary to have the new jitterbuffer on both sides of a call; it works on the receive side only. PLC The new jitterbuffer detects packet loss. PLC is done to try to recreate these lost packets in the codec decoding stage, as the encoded audio is translated to slinear. PLC is also used to mask jitterbuffer growth. This facility is enabled by default in iLBC and speex, as it has no additional cost. This facility can be enabled in adpcm, alaw, g726, gsm, lpc10, and ulaw by setting genericplc = true in the plc section of codecs.conf. Trunk Timestamps To use this, both sides must be using Asterisk v1.2 or later. Setting trunktimestamps=yes in iax.conf will cause your box to send 16-bit timestamps for each trunked frame inside of a trunk frame. This will enable you to use jitterbuffer for an IAX2 trunk, something that was not possible in the old architecture. The other side must also support this functionality, or else, well, bad things will happen. If you don't use trunk timestamps, there's lots of ways the jitterbuffer can get confused because timestamps aren't necessarily sent through the trunk correctly. Communication with Asterisk v1.0.x systems You can set up communication with v1.0.x systems with the new jitterbuffer, but you can't use trunks with trunktimestamps in this communication. If you are connecting to an Asterisk server with earlier versions of the software (1.0.x), do not enable both jitterbuffer and trunking for the involved peers/users in order to be able to communicate. Earlier systems will not support trunktimestamps. You may also compile chan_iax2.c without the new jitterbuffer, enabling the old backwards compatible architecture. Look in the source code for instructions. Testing and monitoring You can test the effectiveness of PLC and the new jitterbuffer's detection of loss by using the new CLI command iax2 test losspct n. This will simulate n percent packet loss coming in to chan_iax2. You should find that with PLC and the new JB, 10 percent packet loss should lead to just a tiny amount of distortion, while without PLC, it would lead to silent gaps in your audio. iax2 show netstats shows you statistics for each iax2 call you have up. The columns are "RTT" which is the round-trip time for the last PING, and then a bunch of stats for both the local side (what you're receiving), and the remote side (what the other end is telling us they are seeing). The remote stats may not be complete if the remote end isn't using the new jitterbuffer. The stats shown are: Jit: The jitter we have measured (milliseconds) Del: The maximum delay imposed by the jitterbuffer (milliseconds) Lost: The number of packets we've detected as lost. %: The percentage of packets we've detected as lost recently. Drop: The number of packets we've purposely dropped (to lower latency). OOO: The number of packets we've received out-of-order Kpkts: The number of packets we've received / 1000. Reporting problems There's a couple of things that can make calls sound bad using the jitterbuffer: The JB and PLC can make your calls sound better, but they can't fix everything. If you lost 10 frames in a row, it can't possibly fix that. It really can't help much more than one or two consecutive frames. Bad timestamps: If whatever is generating timestamps to be sent to you generates nonsensical timestamps, it can confuse the jitterbuffer. In particular, discontinuities in timestamps will really upset it: Things like timestamps sequences which go 0, 20, 40, 60, 80, 34000, 34020, 34040, 34060... It's going to think you've got about 34 seconds of jitter in this case, etc.. The right solution to this is to find out what's causing the sender to send us such nonsense, and fix that. But we should also figure out how to make the receiver more robust in cases like this. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 140 chan_iax2 will actually help fix this a bit if it's more than 3 seconds or so, but at some point we should try to think of a better way to detect this kind of thing and resynchronize. Different clock rates are handled very gracefully though; it will actually deal with a sender sending 20% faster or slower than you expect just fine. Really strange network delays: If your network "pauses" for like 5 seconds, and then when it restarts, you are sent some packets that are 5 seconds old, we are going to see that as a lot of jitter. We already throw away up to the worst 20 frames like this, though, and the "maxjitterbuffer" parameter should put a limit on what we do in this case. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 141 mISDN Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 142 Introduction to mISDN This package contains the mISDN Channel Driver for the Asterisk PBX. It supports every mISDN Hardware and provides an interface for Asterisk. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 143 mISDN Features NT and TE mode PP and PMP mode BRI and PRI (with BNE1 and BN2E1 Cards) Hardware bridging DTMF detection in HW+mISDNdsp Display messages on phones (on those that support it) app_SendText HOLD/RETRIEVE/TRANSFER on ISDN phones : ) Allow/restrict user number presentation Volume control Crypting with mISDNdsp (Blowfish) Data (HDLC) callthrough Data calling (with app_ptyfork +pppd) Echo cancellation Call deflection Some others Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 144 mISDN Fast Installation Guide It is easy to install mISDN and mISDNuser. This can be done by: You can download latest stable releases from http://www.misdn.org/downloads/ Just fetch the newest head of the GIT (mISDN project moved from CVS) In details this process described here: http://www.misdn.org/index.php/GIT then compile and install both with: cd mISDN ; make && make install (you will need at least your kernel headers to compile mISDN). cd mISDNuser ; make && make install Now you can compile chan_misdn, just by making Asterisk: cd asterisk ; ./configure && make && make install That's all! Follow the instructions in the mISDN Package for how to load the Kernel Modules. Also install process described in http://www.misdn.org/index.php/Installi ng_mISDN Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 145 mISDN Pre-Requisites To compile and install this driver, you'll need at least one mISDN Driver and the mISDNuser package. Chan_misdn works with both, the current release version and the development (svn trunk) version of Asterisk. You should use Kernels = 2.6.9 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 146 mISDN Configuration First of all you must configure the mISDN drivers, please follow the instructions in the mISDN package to do that, the main config file and config script is: /etc/init.d/misdn-init and /etc/misdn-init.conf Now you will want to configure the misdn.conf file which resides in the Asterisk config directory (normally /etc/asterisk). misdn.conf: [general] subsection The misdn.conf file contains a "general" subsection, and user subsections which contain misdn port settings and different Asterisk contexts. In the general subsection you can set options that are not directly port related. There is for example the very important debug variable which you can set from the Asterisk cli (command line interface) or in this configuration file, bigger numbers will lead to more debug output. There's also a trace file option, which takes a path+filename where debug output is written to. misdn.conf: [default] subsection The default subsection is another special subsection which can contain all the options available in the user/port subsections. The user/port subsections inherit their parameters from the default subsection. misdn.conf: user/port subsections The user subsections have names which are unequal to "general". Those subsections contain the ports variable which mean the mISDN Ports. Here you can add multiple ports, comma separated. Especially for TE-Mode Ports there is a msns option. This option tells the chan_misdn driver to listen for incoming calls with the given msns, you can insert a '' as single msn, which leads to getting every incoming call. If you want to share on PMP TE S0 with Asterisk and a phone or ISDN card you should insert here the msns which you assign to Asterisk. Finally a context variable resides in the user subsections, which tells chan_misdn where to send incoming calls to in the Asterisk dial plan (extension.conf).* Dial and Options String The dial string of chan_misdn got more complex, because we added more features, so the generic dial string looks like: mISDN/[:bchannel]|g:/[/] The Optionsstring looks Like: ::... The ":" character is the delimiter. The available options are: a - Have Asterisk detect DTMF tones on called channel c - Make crypted outgoing call, optarg is keyindex d - Send display text to called phone, text is the optarg e - Perform echo cancelation on this channel, takes taps as optarg (32,64,128,256) e! - Disable echo cancelation on this channel f - Enable fax detection h - Make digital outgoing call h1 - Make HDLC mode digital outgoing call i - Ignore detected DTMF tones, don't signal them to Asterisk, they will be transported inband. jb - Set jitter buffer length, optarg is length jt - Set jitter buffer upper threshold, optarg is threshold jn - Disable jitter buffer n - Disable mISDN DSP on channel. Disables: echo cancel, DTMF detection, and volume control. p - Caller ID presentation, optarg is either 'allowed' or 'restricted' s - Send Non-inband DTMF as inband vr - Rx gain control, optarg is gain vt - Tx gain control, optarg is gain chan_misdn registers a new dial plan application "misdn_set_opt" when loaded. This application takes the Optionsstring as argument. The Syntax is: Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 147 misdn_set_opt() When you set options in the dialstring, the options are set in the external channel. When you set options with misdn_set_opt, they are set in the current incoming channel. So if you like to use static encryption, the scenario looks as follows: Phone1 --> * Box 1 --> PSTN_TE PSTN_TE --> * Box 2 --> Phone2 The encryption must be done on the PSTN sides, so the dialplan on the boxes are: Box 1: exten => _${CRYPT_PREFIX}X.,1,Dial(mISDN/g:outbound/:c1) Box 2: exten => ${CRYPT_MSN},1,misdn_set_opt(:c1) exten => ${CRYPT_MSN},2,dial(${PHONE2}) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 148 mISDN CLI Commands At the Asterisk cli you can try to type in: misdn Now you should see the misdn cli commands: clean -> pid (cleans a broken call, use with care, leads often to a segmentation fault) send -> display (sends a Text Message to a Asterisk channel, this channel must be an misdn channel) set -> debug (sets debug level) show -> config (shows the configuration options) channels (shows the current active misdn channels) channel (shows details about the given misdn channels) stacks (shows the current ports, their protocols and states) fullstacks (shows the current active and inactive misdn channels) restart -> port (restarts given port (L2 Restart) ) - reload (reloads misdn.conf) You can only use "misdn send display" when an Asterisk channel is created and isdn is in the correct state. "correct state" means that you have established a call to another phone (must not be isdn though). Then you use it like this: misdn send display mISDN/1/101 "Hello World!" where 1 is the Port of the Card where the phone is plugged in, and 101 is the msn (callerid) of the Phone to send the text to. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 149 mISDN Variables mISDN Exports/Imports a few Variables: MISDN_ADDRESS_COMPLETE : Is either set to 1 from the Provider, or you can set it to 1 to force a sending complete.* Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 150 mISDN Debugging and Bug Reports If you encounter problems, you should set up the debugging flag, usually debug=2 should be enough. The messages are divided into Asterisk and mISDN parts. mISDN Debug messages begin with an 'I', Asterisk messages begin with an '', the rest is clear I think.* Please take a trace of the problem and open a report in the Asterisk issue tracker at https://issues.asterisk.org in the "channel drivers" project, "chan_misdn" category. Read the bug guidelines to make sure you provide all the information needed. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 151 mISDN Examples Here are some examples of how to use chan_misdn in the dialplan (extensions.conf): [globals] OUT_PORT=1 ; The physical Port of the Card OUT_GROUP=ExternE1 ; The Group of Ports defined in misdn.conf [misdnIn] exten => _X.,1,Dial(mISDN/${OUT_PORT}/${EXTEN}) exten => _0X.,1,Dial(mISDN/g:${OUT_GROUP}/${EXTEN:1}) exten => _1X.,1,Dial(mISDN/g:${OUT_GROUP}/${EXTEN:1}/:dHello) exten => _1X.,1,Dial(mISDN/g:${OUT_GROUP}/${EXTEN:1}/:dHello Test:n) On the last line, you will notice the last argument (Hello); this is sent as Display Message to the Phone. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 152 mISDN Known Problems Q: I cannot hear any tone after a successful CONNECT to the other end. A: You forgot to load mISDNdsp, which is now needed by chan_misdn for switching and DTMF tone detection. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 153 Local Channel Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 154 Introduction to Local Channels In Asterisk, Local channels are a method used to treat an extension in the dialplan as if it were an external device. In essense, Asterisk will send the call back into the dialplan as the destination of the call, versus sending the call to a device. Two of the most common areas where Local channels are used include members configured for queues, and in use with callfiles. There are also other uses where you want to ring two destinations, but with different information, such as different callerID for each outgoing request. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 155 Local Channel Examples Local channels are best demonstrated through the use of an example. Our first example isn't terribly useful, but will demonstrate how Local channels can execute dialplan logic by dialing from the Dial() application. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 156 Trivial Local Channel Example In our dialplan (extensions.conf), we can Dial() another part of the dialplan through the use Local channels. To do this, we can use the following dialplan: [devices] exten => 201,1,Verbose(2,Dial another part of the dialplan via the Local chan) exten => 201,n,Verbose(2,Outside channel: ${CHANNEL}) exten => 201,n,Dial(Local/201@extensions) exten => 201,n,Hangup() [extensions] exten => 201,1,Verbose(2,Made it to the Local channel) exten => 201,n,Verbose(2,Inside channel: ${CHANNEL}) exten => 201,n,Dial(SIP/some-named-extension,30) exten => 201,n,Hangup() The output of the dialplan would look something like the following. The output has been broken up with some commentary to explain what we're looking at. – Executing [201@devices:1] Verbose("SIP/my_desk_phone-00000014", "2,Dial another part of the dialplan via the Local chan") in new stack == Dial another part of the dialplan via the Local chan We dial extension 201 from SIP/my_desk_phone which has entered the [devices] context. The first line simply outputs some information via the Verbose() application. – Executing [201@devices:2] Verbose("SIP/my_desk_phone-00000014", "2,Outside channel: SIP/my_desk_phone-00000014") in new stack == Outside channel: SIP/my_desk_phone-00000014 The next line is another Verbose() application statement that tells us our current channel name. We can see that the channel executing the current dialplan is a desk phone (aptly named 'my_desk_phone'). – Executing [201@devices:3] Dial("SIP/my_desk_phone-00000014", "Local/201@extensions") in new stack – Called 201@extensions Now the third step in our dialplan executes the Dial() application which calls extension 201 in the [extensions] context of our dialplan. There is no requirement that we use the same extension number - we could have just as easily used a named extension, or some other number. Remember that we're dialing another channel, but instead of dialing a device, we're "dialing" another part of the dialplan. – Executing [201@extensions:1] Verbose("Local/201@extensions-7cf4;2", "2,Made it to the Local channel") in new stack == Made it to the Local channel Now we've verified we've dialed another part of the dialplan. We can see the channel executing the dialplan has changed to Local/201@extensions-7cf4;2. The part '-7cf4;2' is just the unique identifier, and will be different for you. – Executing [201@extensions:2] Verbose("Local/201@extensions-7cf4;2", "2,Inside channel: Local/201@extensions-7cf4;2") in new stack == Inside channel: Local/201@extensions-7cf4;2 Here we use the Verbose() application to see what our current channel name is. As you can see the current channel is a Local channel which we created from our SIP channel. – Executing [201@extensions:3] Dial("Local/201@extensions-7cf4;2", "SIP/some-named-extension,30") in new stack And from here, we're using another Dial() application to call a SIP device configured in sip.conf as [some-named-extension]. Now that we understand a simple example of calling the Local channel, let's expand upon this example by using Local channels to call two devices at the same time, but delay calling one of the devices. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 157 Delay Dialing Devices Example Lets say when someone calls extension 201, we want to ring both the desk phone and their cellphone at the same time, but we want to wait about 6 seconds to start dialing the cellphone. This is useful in a situation when someone might be sitting at their desk, but don't want both devices ringing at the same time, but also doesn't want to wait for the full ring cycle to execute on their desk phone before rolling over to their cellphone. The dialplan for this would look something like the following: [devices] exten => 201,1,Verbose(2,Call desk phone and cellphone but with delay) exten => 201,n,Dial(Local/deskphone-201@extensions&Local/cellphone-201@extensions,30) exten => 201,n,Voicemail(201@default,${IF($[${DIALSTATUS} = BUSY]?b:u)}) exten => 201,n,Hangup() [extensions] ; Dial the desk phone exten => deskphone-201,1,Verbose(2,Dialing desk phone of extension 201) exten => deskphone-201,n,Dial(SIP/0004f2040001) ; SIP device with MAC address ; of 0004f2040001 ; Dial the cellphone exten => cellphone-201,1,Verbose(2,Dialing cellphone of extension 201) exten => cellphone-201,n,Verbose(2,-- Waiting 6 seconds before dialing) exten => cellphone-201,n,Wait(6) exten => cellphone-201,n,Dial(DAHDI/g0/14165551212) When someone dials extension 201 in the [devices] context, it will execute the Dial() application, and call two Local channels at the same time: Local/deskphone-201@extensions Local/cellphone-201@extensions It will then ring both of those extensions for 30 seconds before rolling over to the Voicemail() application and playing the appropriate voicemail recording depending on whether the ${DIALSTATUS} variable returned BUSY or not. When reaching the deskphone-201 extension, we execute the Dial() application which calls the SIP device configured as '0004f204001' (the MAC address of the device). When reaching the cellphone-201 extension, we dial the cellphone via the DAHDI channel using group zero (g0) and dialing phone number 1-416-555-1212. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 158 Dialing Destinations with Different Information With Asterisk, we can place a call to multiple destinations by separating the technology/destination pair with an ampersand (&). For example, the following Dial() line would ring two separate destinations for 30 seconds: exten => 201,1,Dial(SIP/0004f2040001&DAHDI/g0/14165551212,30) That line would dial both the SIP/0004f2040001 device (likely a SIP device on the network) and dial the phone number 1-416-555-1212 via a DAHDI interface. In our example though, we would be sending the same callerID information to both end points, but perhaps we want to send a different callerID to one of the destinations? We can send different callerIDs to each of the destinations if we want by using the Local channel. The following example shows how this is possible because we would Dial() two different Local channels from our top level Dial(), and that would then execute some dialplan before sending the call off to the final destinations. [devices] exten => 201,1,NoOp() exten => 201,n,Dial(Local/201@internal&Local/201@external,30) exten => 201,n,Voicemail(201@default,${IF($[${DIALSTATUS} = BUSY]?b:u)}) exten => 201,n,Hangup() [internal] exten => 201,1,Verbose(2,Placing internal call for extension 201) exten => 201,n,Set(CALLERID(name)=From Sales) exten => 201,n,Dial(SIP/0004f2040001,30) [external] exten => 201,1,Verbose(2,Placing external call for extension 201) exten => 201,n,Set(CALLERID(name)=Acme Cleaning) exten => 201,n,Dial(DAHDI/g0/14165551212) With the dialplan above, we've sent two different callerIDs to the destinations: "From Sales" was sent to the local device SIP/0004f2040001 "Acme Cleaning" was sent to the remote number 1-416-555-1212 via DAHDI Because each of the channels is independent from the other, you could perform any other call manipulation you need. Perhaps the 1-416-555-1212 number is a cell phone and you know you can only ring that device for 18 seconds before the voicemail would pick up. You could then limit the length of time the external number is dialed, but still allow the internal device to be dialed for a longer period of time. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 159 Using Callfiles and Local Channels Another example is to use callfiles and Local channels so that you can execute some dialplan prior to performing a Dial(). We'll construct a callfile which will then utilize a Local channel to lookup a bit of information in the AstDB and then place a call via the channel configured in the AstDB. First, lets construct our callfile that will use the Local channel to do some lookups prior to placing our call. More information on constructing callfiles is located in the doc/callfiles.txt file of your Asterisk source. Our callfile will simply look like the following: Channel: Local/201@devices Application: Playback Data: silence/1&tt-weasels Add the callfile information to a file such as 'callfile.new' or some other appropriately named file. Our dialplan will perform a lookup in the AstDB to determine which device to call, and will then call the device, and upon answer, Playback() the silence/1 (1 second of silence) and the tt-weasels sound files. Before looking at our dialplan, lets put some data into AstDB that we can then lookup from the dialplan. From the Asterisk CLI, run the following command: *CLI> database put phones 201/device SIP/0004f2040001 We've now put the device destination (SIP/0004f2040001) into the 201/device key within the phones family. This will allow us to lookup the device location for extension 201 from the database. We can then verify our entry in the database using the 'database show' CLI command: *CLI> database show /phones/201/device : SIP/0004f2040001 Now lets create the dialplan that will allow us to call SIP/0004f2040001 when we request extension 201 from the extensions context via our Local channel. [devices] exten => 201,1,NoOp() exten => 201,n,Set(DEVICE=${DB(phones/${EXTEN}/device)}) exten => 201,n,GotoIf($[${ISNULL(${DEVICE})}]?hangup) ; if nothing returned, ; then hangup exten => 201,n,Dial(${DEVICE},30) exten => 201,n(hangup(),Hangup() Then, we can perform a call to our device using the callfile by moving it into the /var/spool/asterisk/outgoing/ directory. mv callfile.new /var/spool/asterisks/outgoing* Then after a moment, you should see output on your console similar to the following, and your device ringing. Information about what is going on during the output has also been added throughout. – Attempting call on Local/201@devices for application Playback(silence/1&tt-weasels) (Retry 1) You'll see the line above as soon as Asterisk gets the request from the callfile. – Executing [201@devices:1] NoOp("Local/201@devices-ecf0;2", "") in new stack – Executing [201@devices:2] Set("Local/201@devices-ecf0;2", "DEVICE=SIP/0004f2040001") in new stack This is where we performed our lookup in the AstDB. The value of SIP/0004f2040001 was then returned and saved to the DEVICE channel variable. – Executing [201@devices:3] GotoIf("Local/201@devices-ecf0;2", "0?hangup") in new stack We perform a check to make sure ${DEVICE} isn't NULL. If it is, we'll just hangup here. – Executing [201@devices:4] Dial("Local/201@devices-ecf0;2", "SIP/0004f2040001,30") in new stack – Called 000f2040001 – SIP/0004f2040001-00000022 is ringing Now we call our device SIP/0004f2040001 from the Local channel. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 160 SIP/0004f2040001-00000022 answered Local/201@devices-ecf0;2* We answer the call. > Channel Local/201@devices-ecf0;1 was answered. > Launching Playback(silence/1&tt-weasels) on Local/201@devices-ecf0;1 We then start playing back the files. – Playing 'silence/1.slin' (language 'en') == Spawn extension (devices, 201, 4) exited non-zero on 'Local/201@devices-ecf0;2' At this point we now see the Local channel has been optimized out of the call path. This is important as we'll see in examples later. By default, the Local channel will try to optimize itself out of the call path as soon as it can. Now that the call has been established and audio is flowing, it gets out of the way. – Playing 'tt-weasels.ulaw' (language 'en') [Mar 1 13:35:23] NOTICE[16814]: pbx_spool.c:349 attempt_thread: Call completed to Local/201@devices We can now see the tt-weasels file is played directly to the destination (instead of through the Local channel which was optimized out of the call path) and then a NOTICE stating the call was completed. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 161 Understanding when to use (slash)n Lets take a look at an example that demonstrates when the use of the /n directive is necessary. If we spawn a Local channel which does a Dial() to a SIP channel, but we use the L() option (which is used to limit the amount of time a call can be active, along with warning tones when the time is nearly up), it will be associated with the Local channel, which is then optimized out of the call path, and thus won't perform as expected. This following dialplan will not perform as expected. [services] exten => 2,1,Dial(SIP/PHONE_B,,L(60000:45000:15000)) [internal] exten => 4,1,Dial(Local/2@services) By default, the Local channel will try to optimize itself out of the call path. This means that once the Local channel has established the call between the destination and Asterisk, the Local channel will get out of the way and let Asterisk and the end point talk directly, instead of flowing through the Local channel. This can have some adverse effects when you're expecting information to be available during the call that gets associated with the Local channel. When the Local channel is optimized out of the call path, any Dial() flags, or channel variables associated with the Local channel are also destroyed and are no longer available to Asterisk. We can force the Local channel to remain in the call path by utilizing the /n directive. By adding /n to the end of the channel definition, we can keep the Local channel in the call path, along with any channel variables, or other channel specific information. In order to make this behave as we expect (limiting the call), we would change: [internal] exten => 4,1,Dial(Local/2@services) ...into the following: [internal] exten => 4,1,Dial(Local/2@services/n) By adding /n to the end, our Local channel will now stay in the call path and not go away. Why does adding the /n option all of a suddon make the 'L' option work? First we need to show an overview of the call flow that doesn't work properly, and discuss the information associated with the channels: 1. 2. 3. 4. 5. 6. 7. SIP device PHONE_A calls Asterisk via a SIP INVITE Asterisk accepts the INVITE and then starts processing dialplan logic in the [internal] context Our dialplan calls Dial(Local/2@services) - notice no /n The Local channel then executes dialplan at extension 2 within the [services] context Extension 2 within [services] then performs Dial() to PHONE_B with the line: Dial(SIP/PHONE_B,,L(60000:45000:15000)) SIP/PHONE_B then answers the call Even though the L option was given when dialing the SIP device, the L information is stored in the channel that is doing the Dial() which is the Local channel, and not the endpoint SIP channel. 8. The Local channel in the middle, containing the information for tracking the time allowance of the call, is then optimized out of the call path, losing all information about when to terminate the call. 9. SIP/PHONE_A and SIP/PHONE_B then continue talking indefinitely. Now, if we were to add /n to our dialplan at step three (3) then we would force the Local channel to stay in the call path, and the L() option associated with the Dial() from the Local channel would remain, and our warning sounds and timing would work as expected. There are two workarounds for the above described scenario: 1. Use what we just described, Dial(Local/2@services/n) to cause the Local channel to remain in the call path so that the L() option used inside the Local channel is not discarded when optimization is performed. 2. Place the L() option at the outermost part of the path so that when the middle is optimized out of the call path, the information required to make L() work is associated with the outside channel. The L information will then be stored on the calling channel, which is PHONE_A. For example: Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 162 [services] exten => 2,1,Dial(SIP/PHONE_B) [internal] exten => 4,1,Dial(Local/2@services,,L(60000:45000:15000)); Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 163 Local Channel Modifiers There are additional modifiers for the Local channel as well. They include: 'n' - Adding "/n" at the end of the string will make the Local channel not do a native transfer (the "n" stands for "n"o release) upon the remote end answering the line. This is an esoteric, but important feature if you expect the Local channel to handle calls exactly like a normal channel. If you do not have the "no release" feature set, then as soon as the destination (inside of the Local channel) answers the line and one audio frame passes, the variables and dial plan will revert back to that of the original call, and the Local channel will become a zombie and be removed from the active channels list. This is desirable in some circumstances, but can result in unexpected dialplan behavior if you are doing fancy things with variables in your call handling. 'j' - Adding "/j" at the end of the string allows you to use the generic jitterbuffer on incoming calls going to Asterisk applications. For example, this would allow you to use a jitterbuffer for an incoming SIP call to Voicemail by putting a Local channel in the middle. The 'j' option must be used in conjunction with the 'n' option to make sure that the Local channel does not get optimized out of the call. This option is available starting in the Asterisk 1.6.0 branch. 'm' - Using the "/m" option will cause the Local channel to forward music on hold (MoH) start and stop requests. Normally the Local channel acts on them and it is started or stopped on the Local channel itself. This options allows those requests to be forwarded through the Local channel. This option is available starting in the Asterisk 1.4 branch. 'b' - The "/b" option causes the Local channel to return the actual channel that is behind it when queried. This is useful for transfer scenarios as the actual channel will be transferred, not the Local channel. This option is available starting in the Asterisk 1.6.0 branch. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 164 Mobile Channel chan_mobile pages Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 165 Introduction to the Mobile Channel Asterisk Channel Driver to allow Bluetooth Cell/Mobile Phones to be used as FXO devices, and Headsets as FXS devices. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 166 Mobile Channel Features Multiple Bluetooth Adapters supported. Multiple phones can be connected. Multiple headsets can be connected. Asterisk automatically connects to each configured mobile phone / headset when it comes in range. CLI command to discover bluetooth devices. Inbound calls on the mobile network to the mobile phones are handled by Asterisk, just like inbound calls on a Zap channel. CLI passed through on inbound calls. Dial outbound on a mobile phone using Dial(Mobile/device/nnnnnnn) in the dialplan. Dial a headset using Dial(Mobile/device) in the dialplan. Application MobileStatus can be used in the dialplan to see if a mobile phone / headset is connected. Supports devicestate for dialplan hinting. Supports Inbound and Outbound SMS. Supports 'channel' groups for implementing 'GSM Gateways' Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 167 Mobile Channel Requirements In order to use chan_mobile, you must have a working bluetooth subsystem on your Asterisk box. This means one or more working bluetooth adapters, and the BlueZ packages. Any bluetooth adapter supported by the Linux kernel will do, including usb bluetooth dongles. The BlueZ package you need is bluez-utils. If you are using a GUI then you might want to install bluez-pin also. You also need libbluetooth, and libbluetooth-dev if you are compiling Asterisk from source. You need to get bluetooth working with your phone before attempting to use chan_mobile. This means 'pairing' your phone or headset with your Asterisk box. I dont describe how to do this here as the process differs from distro to distro. You only need to pair once per adapter. See http://www.bluez.org for details about setting up Bluetooth under Linux. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 168 Mobile Channel Concepts chan_mobile deals with both bluetooth adapters and bluetooth devices. This means you need to tell chan_mobile about the bluetooth adapters installed in your server as well as the devices (phones / headsets) you wish to use. chan_mobile currently only allows one device (phone or headset) to be connected to an adapter at a time. This means you need one adapter for each device you wish to use simultaneously. Much effort has gone into trying to make multiple devices per adapter work, but in short it doesnt. Periodically chan_mobile looks at each configured adapter, and if it is not in use (i.e. no device connected) will initiate a search for devices configured to use this adapater that may be in range. If it finds one it will connect the device and it will be available for Asterisk to use. When the device goes out of range, chan_mobile will disconnect the device and the adapter will become available for other devices. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 169 Configuring chan_mobile The configuration file for chan_mobile is /etc/asterisk/mobile.conf. It is a normal Asterisk config file consisting of sections and key=value pairs. See configs/mobile.conf.sample for an example and an explanation of the configuration. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 170 Using chan_mobile chan_mobile.so must be loaded either by loading it using the Asterisk CLI, or by adding it to /etc/asterisk/modules.conf Search for your bluetooth devices using the CLI command 'mobile search'. Be patient with this command as it will take 8 - 10 seconds to do the discovery. This requires a free adapter. Headsets will generally have to be put into 'pairing' mode before they will show up here. This will return something like the following :*CLI> mobile search Address Name Usable Type Port 00:12:56:90:6E:00 LG TU500 Yes Phone 4 00:80:C8:35:52:78 Toaster No Headset 0 00:0B:9E:11:74:A5 Hello II Plus Yes Headset 1 00:0F:86:0E:AE:42 Daves Blackberry Yes Phone 7 This is a list of all bluetooth devices seen and whether or not they are usable with chan_mobile. The Address field contains the 'bd address' of the device. This is like an ethernet mac address. The Name field is whatever is configured into the device as its name. The Usable field tells you whether or not the device supports the Bluetooth Handsfree Profile or Headset profile. The Type field tells you whether the device is usable as a Phone line (FXO) or a headset (FXS) The Port field is the number to put in the configuration file. Choose which device(s) you want to use and edit /etc/asterisk/mobile.conf. There is a sample included with the Asterisk-addons source under configs/mobile.conf.sample. Be sure to configure the right bd address and port number from the search. If you want inbound calls on a device to go to a specific context, add a context= line, otherwise the default will be used. The 'id' of the device [bitinbrackets] can be anything you like, just make it unique. If you are configuring a Headset be sure to include the type=headset line, if left out it defaults to phone. The CLI command 'mobile show devices' can be used at any time to show the status of configured devices, and whether or not the device is capable of sending / receiving SMS via bluetooth. *CLI> mobile show devices ID Address Group Adapter Connected State SMS headset 00:0B:9E:11:AE:C6 0 blue No Init No LGTU550 00:E0:91:7F:46:44 1 dlink No Init No As each phone is connected you will see a message on the Asterisk console :Loaded chan_mobile.so => (Bluetooth Mobile Device Channel Driver) – Bluetooth Device blackberry has connected. – Bluetooth Device dave has connected. To make outbound calls, add something to you Dialplan like the following :- (modify to suit) ; Calls via LGTU5500 exten => _9X.,1,Dial(Mobile/LGTU550/${EXTEN:1},45) exten => _9X.,n,Hangup To use channel groups, add an entry to each phones definition in mobile.conf like group=n where n is a number. Then if you do something like Dial(Mobile/g1/123456) Asterisk will dial 123456 on the first connected free phone in group 1. Phones which do not have a specific 'group=n' will be in group 0. To dial out on a headset, you need to use some other mechanism, because the headset is not likely to have all the needed buttons on it. res_clioriginate is good for this :*CLI> originate Mobile/headset extension NNNNN@context This will call your headset, once you answer, Asterisk will call NNNNN at context context Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 171 Mobile Channel Dialplan Hints chan_mobile supports 'device status' so you can do somthing like exten => 1234,hint,SIP/30&Mobile/dave&Mobile/blackberry Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 172 MobileStatus Application chan_mobile also registers an application named MobileStatus. You can use this in your Dialplan to determine the 'state' of a device. For example, suppose you wanted to call dave's extension, but only if he was in the office. You could test to see if his mobile phone was attached to Asterisk, if it is dial his extension, otherwise dial his mobile phone. exten exten exten exten exten exten => => => => => => 40,1,MobileStatus(dave,DAVECELL) 40,2,GotoIf($["${DAVECELL}" = "1"]?3:5) 40,3,Dial(ZAP/g1/0427466412,45,tT) 40,4,Hangup 40,5,Dial(SIP/40,45,tT) 40,6,Hangup MobileStatus sets the value of the given variable to :- 1 = Disconnected. i.e. Device not in range of Asterisk, or turned off etc etc 2 = Connected and Not on a call. i.e. Free 3 = Connected and on a call. i.e. Busy Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 173 Mobile Channel DTMF Debouncing DTMF detection varies from phone to phone. There is a configuration variable that allows you to tune this to your needs. e.g. in mobile.conf [LGTU550] address=00:12:56:90:6E:00 port=4 context=incoming-mobile dtmfskip=50 change dtmfskip to suit your phone. The default is 200. The larger the number, the more chance of missed DTMF. The smaller the number the more chance of multiple digits being detected. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 174 Mobile Channel SMS Sending and Receiving If Asterisk has detected your mobile phone is capable of SMS via bluetooth, you will be able to send and receive SMS. Incoming SMS's cause Asterisk to create an inbound call to the context you defined in mobile.conf or the default context if you did not define one. The call will start at extension 'sms'. Two channel variables will be available, SMSSRC = the number of the originator of the SMS and SMSTXT which is the text of the SMS. This is not a voice call, so grab the values of the variables and hang the call up. So, to handle incoming SMS's, do something like the following in your dialplan [incoming-mobile] exten => sms,1,Verbose(Incoming SMS from ${SMSSRC} ${SMSTXT}) exten => sms,n,Hangup() The above will just print the message on the console. If you use res_jabber, you could do something like this :- [incoming-mobile] exten => sms,1,JabberSend(transport,user@jabber.somewhere.com,SMS from ${SMSRC} ${SMSTXT}) exten => sms,2,Hangup() To send an SMS, use the application MobileSendSMS like the following :- exten => 99,1,MobileSendSMS(dave,0427123456,Hello World) This will send 'Hello World' via device 'dave' to '0427123456' Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 175 Mobile Channel Debugging Different phone manufacturers have different interpretations of the Bluetooth Handsfree Profile Spec. This means that not all phones work the same way, particularly in the connection setup / initialisation sequence. I've tried to make chan_mobile as general as possible, but it may need modification to support some phone i've never tested. Some phones, most notably Sony Ericsson 'T' series, dont quite conform to the Bluetooth HFP spec. chan_mobile will detect these and adapt accordingly. The T-610 and T-630 have been tested and work fine. If your phone doesnt behave has expected, turn on Asterisk debugging with 'core set debug 1'. This will log a bunch of debug messages indicating what the phone is doing, importantly the rfcomm conversation between Asterisk and the phone. This can be used to sort out what your phone is doing and make chan_mobile support it. Be aware also, that just about all mobile phones behave differently. For example my LG TU500 wont dial unless the phone is a the 'idle' screen. i.e. if the phone is showing a 'menu' on the display, when you dial via Asterisk, the call will not work. chan_mobile handles this, but there may be other phones that do other things too... Important: Watch what your mobile phone is doing the first few times. Asterisk wont make random calls but if chan_mobile fails to hangup for some reason and you get a huge bill from your telco, dont blame me Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 176 Unistim Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 177 Introduction to the Unistim channel Unified Networks IP Stimulus (UNIStim) Channel Driver for Asterisk This is a channel driver for Unistim protocol. You can use a least a Nortel i2002, i2004 and i2050. Following features are supported : Send/Receive CallerID, Redial, SoftKeys, SendText(), Music On Hold, Message Waiting Indication (MWI), Distinctive ring, Transfer, Threeway call, History, Forward, Dynamic SoftKeys. How to configure the i2004 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Power on the phone Wait for message "Nortel Networks" Press quickly the four buttons just below the LCD screen, in sequence from left to right If you see "Locating server", power off or reboot the phone and try again DHCP : 0 SET IP : a free ip of your network NETMSK / DEF GW : netmask and default gateway S1 IP : ip of the asterisk server S1 PORT : 5000 S1 ACTION : 1 S1 RETRY COUNT : 10 S2 : same as S1 How to place a call The line=> entry in unistim.conf does not add an extension in asterisk by default. If you want to do that, add extension=line in your phone context. If you have this entry on unistim.conf : [violet] device=006038abcdef line => 102 then use: exten => 2100,1,Dial(USTM/102@violet) You can display a text with : exten => 555,1,SendText(Sends text to client. Greetings) Rebooting a Nortel phone Press mute,up,down,up,down,up,mute,9,release(red button) Distinctive ring 1. You need to append /r to the dial string. 2. The first digit must be from 0 to 7 (inclusive). It's the 'melody' selection. 3. The second digit (optional) must be from 0 to 3 (inclusive). It's the ring volume. 0 still produce a sound. Select the ring style #1 and the default volume : exten => 2100,1,Dial(USTM/102@violet/r1) Select the ring style #4 with a very loud volume : Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 178 exten => 2100,1,Dial(USTM/102@violet/r43) Country code You can use the following codes for country= (used for dial tone) - us fr au nl uk fi es jp no at nz tw cl se be sg il br hu lt pl za pt ee mx in de ch dk cn If you want a correct ring, busy and congestion tone, you also need a valid entry in indications.conf and check if res_indications.so is loaded. language= is also supported but it's only used by Asterisk (for more information see http://www.voip-info.org/wiki/view/Asterisk+multi-lang uage ). The end user interface of the phone will stay in english. Bookmarks, Softkeys Layout |--------------------| | 5 2 | | 4 1 | | 3 0 | When the second letter of bookmark= is @, then the first character is used for positioning this entry If this option is omitted, the bookmark will be added to the next available sofkey Also work for linelabel (example : linelabel="5@Line 123") You can change a softkey programmatically with SendText(@position@icon@label@extension) ex: SendText(@1@55@Stop Forwd@908) Autoprovisioning This feature must only be used on a trusted network. It's very insecure : all unistim phones will be able to use your asterisk pbx. You must add an entry called template. Each new phones will be based on this profile. You must set a least line=>. This value will be incremented when a new phone is registered. device= must not be specified. By default, the phone will asks for a number. It will be added into the dialplan. Add extension=line for using the generated line number instead. Example : [general] port=5000 autoprovisioning=yes [template] line => 100 bookmark=Support@123 ; Every phone will have a softkey Support If a first phone have a mac = 006038abcdef, a new device named USTM/100@006038abcdef will be created. If a second phone have a mac = 006038000000, it will be named USTM/101@006038000000 and so on. When autoprovisioning=tn, new phones will ask for a tn, if this number match a tn= entry in a device, this phone will be mapped into. Example: [black] tn=1234 line => 100 If a user enter TN 1234, the phone will be known as USTM/100@black. History Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 179 Use the two keys located in the middle of the Fixed feature keys row (on the bottom of the phone) to enter call history. By default, chan_unistim add any incoming and outgoing calls in files (/var/log/asterisk/unistimHistory). It can be a privacy issue, you can disable this feature by adding callhistory=0. If history files were created, you also need to delete them. callhistory=0 will NOT disable normal asterisk CDR logs. Forward This feature requires chan_local (loaded by default) Generic asterisk features You can use the following entries in unistim.conf Billing - accountcode amaflags Call Group - callgroup pickupgroup (untested) Music On Hold - musiconhold Language - language (see section Coutry Code) RTP NAT - nat (control ast_rtp_setnat, default = 0. Obscure behaviour) Trunking It's not possible to connect a Nortel Succession/Meridian/BCM to Asterisk via chan_unistim. Use either E1/T1 trunks, or buy UTPS (UNISTIM Terminal Proxy Server) from Nortel. Wiki, Additional infos, Comments : http://www.voip-info.org/wiki-Asterisk+UNISTIM+channels *BSD : Comment #define HAVE_IP_PKTINFO in chan_unistim.c Set public_ip with an IP of your computer Check if unistim.conf is in the correct directory Issues As always, NAT can be tricky. If a phone is behind a NAT, you should port forward UDP 5000 (or change general port= in unistim.conf) and UDP 10000 (or change yourphone rtp_port=) Only one phone per public IP (multiple phones behind the same NAT don't work). You can either : Setup a VPN Install asterisk inside your NAT. You can use IAX2 trunking if you're master asterisk is outside. If asterisk is behind a NAT, you must set general public_ip= with your public IP. If you don't do that or the bindaddr is invalid (or no longer valid, eg dynamic IP), phones should be able to display messages but will be unable to send/receive RTP packets (no sound) Don't forget : this work is based entirely on a reverse engineering, so you may encounter compatibility issues. At this time, I know three ways to establish a RTP session. You can modify yourphone rtp_method= with 0, 1, 2 or 3. 0 is the default method, should work. 1 can be used on new firmware (black i2004) and 2 on old violet i2004. 3 can be used on black i2004 with chrome. If you have difficulties, try unistim debug and set verbose 3 on the asterisk CLI. For extra debug, uncomment #define DUMP_PACKET 1 and recompile chan_unistim. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 180 Protocol information Protocol versions 31 October 2008 UNIStim Firmware Release 3.1 for IP Phones, includes: 0604DCG for Phase II IP Phones (2001, 2002 2004), 0621C6H for IP Phone 2007, 0623C6J, 0624C6J, 0625C6J and 0627C6J for IP Phone 1110, 1120E,1140E and 1150E respectively 062AC6J for IP Phone 1210, 1220, and 1230 27 February 2009 UNIStim Firmware Release 3.2 for IP Phones, including: 0604DCJ for Phase II IP Phones (2001, 2002 & 2004), 0621C6M for IP Phone 2007, 0623C6N, 0624C6N, 0625C6N and 0627C6N for IP Phone 1110, 1120E,1140E and 1150E respectively 062AC6N for IP Phone 1210, 1220, and 1230 30 June 2009 UNIStim Firmware Release 3.3 for IP Phones: 0604DCL for Phase II IP Phones (2001, 2002 & 2004), 0621C6P for IP Phone 2007, 0623C6R, 0624C6R, 0625C6R and 0627C6R for IP Phone 1110, 1120E,1140E and 1150E respectively 062AC6R for IP Phone 1210, 1220, and 1230 27 November 2009 UNIStim Software Release 4.0 for IP Phones, includes: 0621C7A for IP Phone 2007, 0623C7F, 0624C7F, 0625C7F and 0627C7F for IP Phone 1110, 1120E,1140E and 1150E respectively 062AC7F for IP Phone 1210, 1220, and 1230 28 February 2010 UNIStim Software Release 4.1 IP Deskphone Software 0621C7D / 2007 IP Deskphone 0623C7J / 1110 IP Deskphone 0624C7J / 1120E IP Deskphone 0625C7J / 1140E IP Deskphone 0627C7J / 1150E IP Deskphone 0626C7J / 1165E IP Deskphone 062AC7J / 1210 IP Deskphone 062AC7J / 1220 IP Deskphone 062AC7J / 1230 IP Deskphone 29 2010 UNIStim Software Release 4.2 IP Deskphone Software 0621C7G / 2007 IP Deskphone 0623C7M / 1110 IP Deskphone 0624C7M / 1120E IP Deskphone 0625C7M / 1140E IP Deskphone 0627C7M / 1150E IP Deskphone 0626C7M / 1165E IP Deskphone 062AC7M / 1210 IP Deskphone 062AC7M / 1220 IP Deskphone 062AC7M / 1230 IP Deskphone Protocol description Query Audio Manager (16 xx 00 xx…) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 181 Note: Ensure that the handshake commands 1A 04 01 08 1A 07 07 01 23 45 67 are sent to i2004 before sending the commands in column 2. (Requests attributes of the Audio manager) 16 05 00 01 00 Note: Last byte can contain any value. The message length should be 5. If the length is wrong it is ignored e.g. send 16 04 00 01 16 06 00 01 00 03 (Requests options setting of the Audio manager) 16 05 00 02 03 Note: Last byte can contain any value. The message length should be 5. If the length is wrong it is ignored. (Requests Alerting selection) 16 05 00 04 0F Note: Last byte can contain any value. The message length should be 5. If the length is wrong it is ignored. (Requests adjustable Rx volume information command) 16 05 00 08 00 Note: Last byte can contain any value. The message length should be 5. If the length is wrong it is ignored. (Requests the i2004 to send the APB's Default Rx Volume command. The APB Number or stream based tone is provided in the last byte of the command below) 16 05 00 10 00 (none) 16 05 00 10 01 (Audio parameter bank 1, NBHS) 16 05 00 10 02 (Audio parameter bank 2, NBHDS) 16 05 00 10 03 (Audio parameter bank 3, NBHF) 16 05 00 10 04 (Audio parameter bank 4, WBHS) 16 05 00 10 05 (Audio parameter bank 5, WBHDS) 16 05 00 10 06 (Audio parameter bank 6, WBHF) 16 05 00 10 07 (Audio parameter bank 7,) 16 05 00 10 08 (Audio parameter bank 8,) 16 05 00 10 09 (Audio parameter bank 9,) 16 05 00 10 0A (Audio parameter bank 0xA,) 16 05 00 10 0B (Audio parameter bank 0xB,) 16 05 00 10 0C (Audio parameter bank 0xC,) 16 05 00 10 0D (Audio parameter bank 0xD,) 16 05 00 10 0E (Audio parameter bank 0xE,) 16 05 00 10 0F (Audio parameter bank 0xF,) 16 05 00 10 10 (Alerting tone) 16 05 00 10 11 (Special tones) 16 05 00 10 12 (Paging tones) 16 05 00 10 13 (Not Defined) 16 05 00 10 1x (Not Defined) (Set the volume range in configuration message for each of the APBs and for alerting, paging and special tones (see below) and then send the following commands) (Requests handset status, when NBHS is 1) connected 2) disconnected) 16 05 00 40 09 Note: Last byte can contain any value. The message length should be 5. If the length is wrong it is ignored (Requests headset status, when HDS is disconnected) 16 05 00 80 0A (Requests headset status, when HDS is connected) 16 05 00 80 0A Note: Last byte can contain any value. The message length should be 5. If the length is wrong it is ignored (Requests handset and headset status when NBHS and HDS are disconnected) 16 05 00 C0 05 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 182 (Requests handset and headset status when NBHS and HDS are connected) 16 05 00 C0 05 (Send an invalid message) 16 03 00 (Send an invalid message. Is this an invalid msg??) 16 06 00 22 22 22 Query Supervisory headset status (16 03 01) 16 03 01 Audio Manager Options (16 04 02 xx) (Maximum tone volume is one level lower than physical maximum Volume level adjustments are not performed locally in the i2004 Adjustable Rx volume reports not sent to the NI when volume keys are pressed Single tone frequency NOT sent to HS port while call in progress. Single tone frequency NOT sent to HD port while call in progress. Automatic noise squelching disabled. HD key pressed command sent when i2004 receives make/break sequence.) 16 04 02 00 (Maximum tone volume is set to the physical maximum) 16 04 02 01 then requests options setting of the Audio manager by sending 16 04 00 02) (Volume level adjustments are performed locally in the i2004) 16 04 02 02 (then requests options setting of the Audio manager by sending 16 04 00 02) (Adjustable Rx volume reports sent to the NI when volume keys are pressed) 16 04 02 04 (then requests options setting of the Audio manager by sending 16 04 00 02) (Single tone frequency sent to HS port while call in progress) 16 04 02 08 (then requests options setting of the Audio manager by sending 16 04 00 02) (Single tone frequency sent to HD port while call in progress) 16 04 02 10 (then requests options setting of the Audio manager by sending 16 04 00 02) (Automatic noise squelching enabled.) 16 04 02 20 (then requests options setting of the Audio manager by sending 16 04 00 02) (Headset Rfeature Key Pressed command sent when i2004 receives make/break sequence.) 16 04 02 40 (then requests options setting of the Audio manager by sending 16 04 00 02) (In this case both bit 1 and bit 3 are set, hence Volume level adjustments are performed locally in the i2004 and Single tone frequency sent to HS port while call in progress.) 16 04 02 0A Mute/un-mute (16 xx 04 xx...) (In this case two phones are conneted. Phone 1 is given the ID 47.129.31.35 and phone 2 is given the ID 47.129.31.36. Commands are sent to phone 1 ) (TX is muted on stream ID 00) 16 05 04 01 00 (TX is un-muted on stream ID 00) 16 05 04 00 00 (RX is muted on stream ID 00) 16 05 04 03 00 (RX is un-muted on stream ID 00) 16 05 04 02 00 (TX is muted on stream ID 00, Rx is un-muted on stream ID 00) 16 07 04 01 00 02 00 (TX is un-muted on stream ID 00, Rx is muted on stream ID 00) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 183 16 07 04 00 00 03 00 (TX is un-muted on stream ID 00, Rx is un-muted on stream ID 00) 16 07 04 00 00 02 00 Transducer Based tone on (16 04 10 xx) (Alerting on) 16 04 10 00 (Special tones on, played at down loaded tone volume level) 16 04 10 01 (paging on) 16 04 10 02 (not defined) 16 04 10 03 (Alerting on, played at two steps lower than down loaded tone volume level) 16 04 10 08 (Special tones on, played at two steps lower than down loaded tone volume level) 16 04 10 09 Transducer Based tone off (16 04 10 xx) 16 04 11 00 (Alerting off) 16 04 11 01 (Special tones off) 16 04 11 02 (paging off) 16 04 11 03 (not defined) Alerting tone configuration (16 05 12 xx xx) (Note: Volume range is set here for all tones. This should be noted when testing the volume level message) (HF speaker with different warbler select values, tone volume range set to max) 16 05 12 10 00 16 05 12 11 0F 16 05 12 12 0F 16 05 12 13 0F 16 05 12 14 0F 16 05 12 15 0F 16 05 12 16 0F 16 05 12 17 0F (HF speaker with different cadence select values, tone volume range set to max) 16 05 12 10 0F 16 05 12 10 1F 16 05 12 10 2F 16 05 12 10 3F 16 05 12 10 4F 16 05 12 10 5F 16 05 12 10 6F 16 05 12 10 7F (configure cadence with alerting tone cadence download message before sending this message) (HS speaker with different warbler select values, tone volume level set to max) 16 05 12 00 0F 16 05 12 01 0F 16 05 12 02 0F 16 05 12 03 0F 16 05 12 04 0F 16 05 12 05 0F 16 05 12 06 0F 16 05 12 07 0F (HS speaker with different cadence select values, tone volume range set to max) 16 05 12 00 0F 16 05 12 00 1F 16 05 12 00 2F 16 05 12 00 3F 16 05 12 00 4F 16 05 12 00 5F Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 184 16 05 12 00 6F 16 05 12 00 7F (configure cadence with alerting tone cadence download message before sending this message) (HD speaker with different warbler select values, tone volume range set to max) 16 05 12 08 0F 16 05 12 09 0F 16 05 12 0A 0F 16 05 12 0B 0F 16 05 12 0C 0F 16 05 12 0D 0F 16 05 12 0E 0F 16 05 12 0F 0F (HD speaker with different cadence select values, tone volume level set to max) 16 05 12 08 0F 16 05 12 08 1F 16 05 12 08 2F 16 05 12 08 3F 16 05 12 08 4F 16 05 12 08 5F 16 05 12 08 6F 16 05 12 08 7F (configure cadence with alerting tone cadence download message before sending this message) Special tone configuration (16 06 13 xx xx) (Note: Volume range is set here for all tones. This should be noted when testing the volume level message) (HF speaker with different tones, tone volume range is varied) 16 06 13 10 00 01 16 06 13 10 01 01 16 06 13 10 08 01 16 06 13 10 02 07 16 06 13 10 03 07 16 06 13 10 04 11 16 06 13 10 05 11 16 06 13 10 06 18 16 06 13 10 07 18 16 06 13 10 08 1F (HF speaker with different cadences and tones; tone volume level is varied) 16 06 13 10 00 01 16 06 13 10 10 01 16 06 13 10 20 07 16 06 13 10 30 07 16 06 13 10 40 11 16 06 13 10 50 11 16 06 13 10 60 18 16 06 13 10 70 18 (configure cadence with special tone cadence download message before sending this message) (HS speaker with different tones, tone volume range is varied) 16 06 13 00 00 01 16 06 13 00 01 01 16 06 13 00 02 07 16 06 13 00 03 07 16 06 13 00 04 11 16 06 13 00 05 11 16 06 13 00 06 18 16 06 13 00 07 18 (HS speaker with different cadences and tones; tone volume range is varied) 16 06 13 00 00 01 16 06 13 00 10 01 16 06 13 00 20 07 16 06 13 00 30 07 16 06 13 00 40 11 16 06 13 00 50 11 16 06 13 00 60 18 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 185 16 06 13 00 70 18 (configure cadence with special tone cadence download message before sending this message) (HD speaker with different tones, tone volume range is varied) 16 06 13 08 00 01 16 06 13 08 01 01 16 06 13 08 02 07 16 06 13 08 03 07 16 06 13 08 04 11 16 06 13 08 05 11 16 06 13 08 06 18 16 06 13 08 07 18 (HD speaker with different cadences and tones; tone volume range is varied) 16 06 13 08 00 01 16 06 13 08 10 01 16 06 13 08 20 07 16 06 13 08 30 07 16 06 13 08 40 11 16 06 13 08 50 11 16 06 13 08 60 18 16 06 13 08 70 18 (configure cadence with special tone cadence download message before sending this message) Paging tone configuration (16 05 14 xx xx) (Note: Volume range is set here for all tones. This should be noted when testing the volume level message) (HF speaker with different cadence select values, tone volume range set to max) 16 05 14 10 0F 16 05 14 10 1F 16 05 14 10 2F 16 05 14 10 3F 16 05 14 10 4F 16 05 14 10 5F 16 05 14 10 6F 16 05 14 10 7F (configure cadence with paging tone cadence download message before sending this message) (HS speaker with different cadence select values, tone volume range set to max) 16 05 14 00 0F 16 05 14 00 1F 16 05 14 00 2F 16 05 14 00 3F 16 05 14 00 4F 16 05 14 00 5F 16 05 14 00 6F 16 05 14 00 7F (configure cadence with paging tone cadence download message before sending this message) (HD speaker with different cadence select values, tone volume level set to max) 16 05 14 08 0F 16 05 14 08 1F 16 05 14 08 2F 16 05 14 08 3F 16 05 14 08 4F 16 05 14 08 5F 16 05 14 08 6F 16 05 14 08 7F (configure cadence with paging tone cadence download message before sending this message) Alerting Tone Cadence Download (16 xx 15 xx xx...) 16 08 15 00 0A 0f 14 1E (.5 sec on, 0.75 sec off; 1 sec on 1.5 sec off, cyclic) 16 0C 15 01 0A 0f 14 1E 05 0A 0A 14 (.5 sec on, 0.75 sec off; 1 sec on 1.5 sec off; 0.25sec on, 0.5sec off; 0.5 sec on, 1 sec off , one shot) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 186 Special Tone Cadence Download (16 xx 16 xx xx...) 16 05 16 0A 10 (125ms on, 200 ms off) 16 09 16 0A 10 14 1E (125ms on, 200 ms off; 250ms on, 375ms off ) Paging Tone Cadence Download (16 xx 17 xx xx...) 16 06 17 01 0A 10 (125ms on, 200 ms off, 250HZ) 16 06 17 04 05 10 (62.5ms on, 200 ms off, 500 Hz) 16 09 17 01 0A 10 10 14 1E (125ms on, 200 ms off; 250ms on, 375ms off, 250 Hz, 100Hz ) 16 0C 17 01 0A 10 04 14 1E 10 0A 10 (125ms on, 200 ms off; 250ms on, 375ms off; 125ms on, 200 ms off, 250Hz, 1000Hz, 500 Hz ) 16 0C 17 01 1E 10 12 3c 1E 10 28 10 (375ms on, 200 ms off; 750ms on, 375ms off; 500ms on, 200 ms off, 250Hz, (333Hz,1000Hz), 500 Hz ) Transducer Based Tone Volume Level (16 04 18 xx) (Ensure that the volume range is set properly in the alerting, special and paging tone configuration e.g if the volume range is set to zero, this message will always output max volume) (Different volume level for alerting tone. Note: Send the command below and then send the alerting on command and alerting off commands) 16 04 18 00 16 04 18 10 16 04 18 20 16 04 18 30 16 04 18 40 16 04 18 50 16 04 18 60 16 04 18 70 16 04 18 80 16 04 18 90 16 04 18 F0 (HF:Volume range for alerting tone is changed here using these commands) 16 05 12 10 0F 16 05 12 10 00 16 05 12 10 04 (HD:Volume range for alerting tone is changed here using these commands) 16 05 12 08 0F 16 05 12 08 00 16 05 12 08 04 (Different volume level for special tone) 16 04 18 01 16 04 18 11 16 04 18 21 16 04 18 31 16 04 18 41 16 04 18 51 16 04 18 61 16 04 18 71 16 04 18 81 16 04 18 91 16 04 18 A1 16 04 18 B1 16 04 18 C1 16 04 18 D1 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 187 16 04 18 E1 16 04 18 F1 (HF:Volume range for special tone is changed here using these commands) 16 06 13 10 20 07 16 06 13 10 25 07 16 06 13 10 2F 07 (HD:Volume range for special tone is changed here using these commands) 16 06 13 08 20 07 16 06 13 08 25 07 16 06 13 08 2F 07 (Different volume level for paging tone) 16 04 18 02 16 04 18 12 16 04 18 22 16 04 18 32 16 04 18 42 16 04 18 52 16 04 18 62 16 04 18 72 16 04 18 82 16 04 18 92 16 04 18 F2 (HF:Volume range for paging tone is changed here using these commands) 16 05 14 10 0F 16 06 14 10 00 16 06 14 10 04 (HD:Volume range for paging tone is changed here using these commands) 16 06 14 08 0F 16 06 14 08 00 16 06 14 08 04 Alerting Tone Test (16 04 19 xx) (tones 667Hz, duration 50 ms and 500Hz duration 50 ms) 16 04 19 00 (tones 333Hz, duration 50 ms and 250Hz duration 50 ms) 16 04 19 01 (tones 333 Hz + 667 Hz duration 87.5 ms and 500Hz + 1000Hz duration 87.5 ms) 16 04 19 02 (tones 333 Hz, duration 137.5 ms; 500Hz duration 75 ms; 667Hz duration 75 ms) 16 04 19 03 (tones 500Hz, duration 100 ms and 667Hz duration 100 ms) 16 04 19 04 (tones 500Hz, duration 400 ms and 667Hz duration 400 ms) 16 04 19 05 (tones 250Hz, duration 100 ms and 333Hz duration 100 ms) 16 04 19 06 (tones 250Hz, duration 400 ms and 333 Hz, duration 400ms) 16 04 19 07 Visual Transducer Based Tones Enable (16 04 1A xx) Visual tone enabled 16 04 1A 01 (Visual tone disabled) 16 04 1A 00 Stream Based Tone On (16 06 1B xx xx xx) (Dial tone is summed with data on Rx stream 00 at volume level -3dBm0) 16 06 1B 00 00 08 (Dial tone replaces the voice on Rx stream 00 at volume level -6dBm0) 16 06 1B 80 00 10 (Dial tone is summed with voice on Tx stream 00 at volume level -3dBm0) 16 06 1B 40 00 08 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 188 (Dial tone replaces the voice on Tx stream 00 at volume level -3dBm0) 16 06 1B C0 00 08 (Line busy tone is summed with data on Rx stream 00 at volume level -3dBm0) 16 06 1B 02 00 08 (Line busy tone replaces the voice on Rx stream 00 at volume level -6dBm0) 16 06 1B 82 00 10 (Line busy tone is summed with voice on Tx stream 00 at volume level -3dBm0) 16 06 1B 42 00 08 (Line busy tone replaces the voice on Tx stream 00 at volume level -3dBm0) 16 06 1B C2 00 08 (ROH tone is summed with data on Rx stream 00 at volume level -3dBm0) 16 06 1B 05 00 08 (ROH tone replaces the voice on Rx stream 00 at volume level -6dBm0) 16 06 1B 85 00 10 (ROH tone is summed with voice on Tx stream 00 at volume level -3dBm0) 16 06 1B 45 00 08 (ROH tone replaces the voice on Tx stream 00 at volume level -3dBm0) 16 06 1B C5 00 08 (Recall dial tone is summed with data on Rx stream 00 at volume level -3dBm0) 16 06 1B 01 00 08 (Recall dial tone replaces the voice on Rx stream 00 at volume level -6dBm0) 16 06 1B 81 00 10 (Reorder tone is summed with data on Rx stream 00 at volume level -3dBm0) 16 06 1B 03 00 08 (Reorder dial tone replaces the voice on Rx stream 00 at volume level -6dBm0) 16 06 1B 83 00 10 (Audible Ringing tone is summed with data on Rx stream 00 at volume level -3dBm0) 16 06 1B 04 00 08 (Audible Ringing tone replaces the voice on Rx stream 00 at volume level -6dBm0) 16 06 1B 84 00 10 (Stream based tone ID 06 is summed with data on Rx stream 00 at volume level -3dBm0; Tone ID 06 is downloaded using both the frequency and cadence down load commands) 16 06 1B 06 00 08 (Stream based tone ID 06 replaces the voice on Rx stream 00 at volume level -6dBm0) 16 06 1B 86 00 10 (Stream based tone ID 0F is summed with data on Rx stream 00 at volume level -3dBm0; Tone ID 0x0F is downloaded using both the frequency and cadence down load commands) 16 06 1B 0F 00 08 (Stream based tone ID 0F replaces the voice on Rx stream 00 at volume level -6dBm0) 16 06 1B 8F 00 10 Stream Based Tone Off (16 05 1C xx xx) (Dial tone is turned off on Rx stream 00) 16 05 1C 00 00 (Dial tone is turned off on Tx stream 00) 16 05 1C 40 00 (Line busy tone is turned off on Rx stream 00) 16 05 1C 02 00 (Line busy tone is turned off on Tx stream 00) 16 05 1C 42 00 (ROH tone is turned off on Rx stream 00) 16 05 1C 05 00 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 189 (ROH tone is turned off on Tx stream 00) 16 05 1C 45 00 (Recall dial tone is turned off on Rx stream 00) 16 05 1C 01 00 (Reorder tone is turned off on Rx stream 00) 16 05 1C 03 00 (Audible Ringing tone is turned off on Rx stream 00) 16 05 1C 04 00 (Stream based tone ID 06 is turned off on Rx stream 00) 16 05 1C 06 00 (Stream based tone ID 0F is turned off on Rx stream 00) 16 05 1C 0F 00 Stream Based Tone Frequency Component List Download (up to 4 frequencies can be specified) (16 xx 1D xx...) Note: Frequency component download and cadence download commands sent to the i2004 first. Then send the stream based tone ID on command to verify that tones are turned on. 16 06 1D 06 2C CC (1400Hz ) 16 08 1D 07 2C CC 48 51 (1400 Hz and 2250Hz) Stream Based Tone Cadence Download (up to 4 cadences can be specified) (16 xx 1E xx...) Note: Frequency component download and cadence download commands sent to the i2004 first. Then send the stream based tone ID on command to verify that tones are turned on. 16 06 1E 26 0A 0A (200 ms on and 200 ms off with tone turned off after the full sequence) 16 08 1E 07 0A 0A 14 14 (20 ms on and 20 ms off for first cycle, 400 ms on and 400 ms off fo rthe second cycle with sequence repeated) 16 05 1E 26 0A (In this case tone off period is not specified hence tone is played until stream based tone off command is received. Select Adjustable Rx Volume (16 04 20 xx) 16 04 20 01 (Audio parameter block 1) 16 04 20 03 (Audio parameter block 3) 16 04 20 08 (Alerting Rx volume) 16 04 20 09 (Special tone Rx volume) 16 04 20 0a (Paging tone Rx volume) Set APB's Rx Volume Levels (16 05 21 xx xx) 16 05 21 01 25 (? Rx volume level 5 steps louder than System RLR) 16 05 21 01 05 (? Rx volume level 5 steps quieter than System RLR) Change Adjustable Rx Volume 16 03 22 (Rx volume level is one step quieter for the APB/tones selected through Select Adjustable Rx Volume command) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 190 16 03 23 (Rx volume level is one step louder for the APB/tones selected through Select Adjustable Rx Volume command) Adjust Default Rx Volume (16 04 24 xx) 16 04 24 01 (Default Rx volume level is one step quieter for the APB 1) 16 04 25 01 (Default Rx volume level is one step louder for the APB 1) Adjust APB's Tx and/or STMR Volume Level (16 04 26 xx) (First ensure that the Tx and STMR volume level are set to maximum by repeatedly (if needed) sending the command 16 04 26 F2 to APB2. Rest of the commands are sent to i2004 individually and then the query command below is used to verify if the commands are sent correctly) (Enable both Tx Vol adj. and STMR adj; Both Tx volume and STMR volume are one step louder on APB 2) 16 04 26 F2 (Enable both Tx Vol adj. and STMR adj; Both Tx volume and STMR volume are one step quieter on APB 2) 16 04 26 A2 (Enable Tx Vol adj. and disable STMR adj; Tx volume is one step louder on APB 3) 16 04 26 C3 (Enable Tx Vol adj. and disable STMR adj; Tx volume is one step quieter on APB 3) 16 04 26 83 (Disable both Tx Vol adj. and STMR adj on APB 1) 16 04 26 01 Query APB's Tx and/or STMR Volume Level (16 04 27 XX) (Query Tx volume level and STMR volume level on APB 2) 16 04 27 32 (Query STMR volume level on APB 1) 16 04 27 11 (Query STMR volume level on APB 2) 16 04 27 12 (Query STMR volume level on APB 3) 16 04 27 13 (Query Tx volume level on APB 1) 16 04 27 21 (Query Tx volume level on APB 2) 16 04 27 22 (Query Tx volume level on APB 3) 16 04 27 23 APB Download (16 xx-1F xx...) 16 09 28 FF AA 88 03 00 00 Open Audio Stream (16 xx 30 xx...) (If Audio stream is already open it has to be closed before another open audio stream command is sent) 16 15 30 00 00 00 00 01 00 13 89 00 00 13 89 00 00 2F 81 1F 23 (Open G711 ulaw Audio stream to 2F.81.1F.9F) 16 15 30 00 00 08 08 01 00 13 89 00 00 13 89 00 00 2F 81 1F 23 (Open G711 Alaw Audio stream to 2F.81.1F.9F) 16 15 30 00 00 12 12 01 00 13 89 00 00 13 89 00 00 2F 81 1F 23 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 191 (Open G729 Audio stream to 2F.81.1F.9F) 16 15 30 00 00 04 04 01 00 13 89 00 00 13 89 00 00 2F 81 1F 23 (Open G723? ulaw Audio stream to 2F.81.1F.9F) Close Audio Stream (16 05 31 xx xx) 16 05 31 00 00 Connect Transducer (16 06 32 xx xx xx) 16 06 32 C0 11 00 (Connect the set in Handset mode with no side tone) 16 06 32 C0 01 00 (Connect the set in Handset mode with side tone) 16 06 32 C1 12 00 (Connect the set in Headset mode with no side tone) 16 06 32 C1 02 00 (Connect the set in Headset mode with side tone) 16 06 32 C2 03 00 (Connect the set in Hands free mode) Frequency Response Specification (16 xx 33 xx...) Filter Block Download 16 xx 39 xx Voice Switching debug 16 04 35 11 (Full Tx, Disable switch loss bit) 16 04 35 12 (Full Rx, Disable switch loss bit) Voice Switching Parameter Download 16 08 36 01 2D 00 00 02 (APB 1, AGC threshold index 0, Rx virtual pad 0, Tx virtual pad 0, dynamic side tone enabled) Query RTCP Statistics 16 04 37 12 (queries RTCP bucket 2, resets RTCP bucket info.) Configure Vocoder Parameters 16 0A 38 00 00 CB 00 E0 00 A0 (For G711 ulaw 20 ms, NB) 16 0A 38 00 08 CB 00 E0 00 A0 (G711 Alaw 20 ms, NB) 16 0A 38 00 00 CB 01 E0 00 A0 (For G711 ulaw 10 ms, WB) 16 0A 38 00 08 CB 01 E0 00 A0 (G711 Alaw 10 ms, WB) 16 08 38 00 12 C1 C7 C5 (For G729 VAD On, High Pass Filter Enabled, Post Filter Enabled) 16 09 38 00 04 C9 C5 C7 C1 (G723 VAD On, High Pass Filter Enabled, Post Filter Enabled at 5.3 KHz) 16 09 38 00 04 C0 C7 C5 C9 (G723 VAD Off, High Pass Filter Enabled, Post Filter Enabled at 5.3 KHz) 16 09 38 00 04 C1 C5 C7 C8 (G723 VAD On, High Pass Filter Enabled, Post Filter Enabled at 6.3 KHz) 16 09 38 00 04 C0 C7 C5 C8 (G723 VAD Off, High Pass Filter Enabled, Post Filter Enabled at 6.3 KHz) Query RTCP Bucket's SDES Information (39 XX) (The first nibble in the last byte indicates the bucket ID) 16 04 39 21 16 04 39 22 16 04 39 23 16 04 39 24 16 04 39 25 16 04 39 26 16 04 39 27 16 04 39 01 16 04 39 12 16 04 39 23 16 04 39 34 16 04 39 45 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 192 16 04 39 56 16 04 39 67 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 193 Skinny chan_skinny stuff Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 194 Skinny call logging Page for details about call logging. Calls are logged in the devices placed call log (directories->Place Calls) when a call initially connects to another device. Subsequent changes in the device (eg forwarded) are not reflected in the log. If a call is not placed to a channel they will not be recorded in the log. eg a call to voicemail will not be recorded. You can force these to be recorded by including progress(), then ringing() in the dialplan. Example (This will produce a logged call): exten exten exten exten => => => => 100,1,NoOp 100,n,Progress 100,n,Ringing 100,n,VoicemailMain(${CALLERID(num)@mycontext,s) Example (This will not): exten => 100,1,NoOp exten => 100,n,VoicemailMain(${CALLERID(num)@mycontext,s) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 195 Skinny Dev Notes A spot to keep development notes. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 196 Keepalives Been doing some mucking around with cisco phones. Things found out about keepalives documented here. It appears the minimum keepalive is 10. Any setting below this reverts to the the device setting 10 seconds. Keepalive timings seem to vary by device type (and probably firmware). Device F/Ware Proto 1st KA Behavior w/ no response 7960 7.2(3.0) 6 15 Sec KA, KA, KA, UNREG 7961 8.5.4(1.6 17 As set KA, KA*2, KA*2, UNREG 7920 4.0-3-2 5 As set KA, KA, KA, KA+Reset Conn For example, with keepalive set to 20: the 7960 will UNREG in 75 sec (ka@15, ka@35, ka@55, unreg@75) (straight after registration); or the 7960 will UNREG in 80 sec (ka@20, ka@40, ka@60, unreg@80) (after 1 keepalive ack sent); the 7961 will UNREG in 120 sec (ka@20, ka@60, ka@100, unreg@120). Other info: Devices appear to consider themselves still registered (with no indication provided to user) until the unregister/reset conn occurs. Devices generally do not respond to keepalives or reset their own timings (see below for exception) After unregister (but no reset obviously) keepalives are still sent, further, the device now responds to keepalives with a keepalive_ack, but this doesn't affect the timing of their own keepalives. chan_skinny impact: need to revise keepalive timing with is currently set to unregister at 1.1 * keepalive time Testing wifi (7920 with keepalive set to 20), immediately after a keepalive: removed from range for 55 secs - at 58 secs 3 keepalives received, connection remains. removed from range for 65 secs - at about 80 secs, connection reset and device reloads. server set to ignore 2 keepalives - 3rd keepalive at just under 60secs, connection remains. server set to ignore 3 keepalives - 4th keepalive at just under 80secs, connection reset by device anyway. looks like timing should be about 3*keepalive (ie 60secs), maybe 5*keepalive for 7961 (v17?) More on ignoring keepalives at the server (with the 7920) (table below) if keepalive is odd, the time used is rounded up to the next even number (ie 15 will result in 16 secs) the first keepalive is delayed by 1 sec if keepalive is less than 30, 15 secs if less than 120, else 105 secs these two lead to some funny numbers if set to 119, the first will be at 135 secs (119 rounded up + 15), and subsequent each 120 secs if set to 120, the first will be at 225 secs (120 not rounded + 105), and subsequent each 120 secs similarly if set to 29, the first will be 31 then 30, where if set to 30 the first will be 45 then 30 only tested out to 600 secs (where the first is still delayed by 105 secs) device resets the connection 20 secs after the 3rd unreplied keepalive keepalives below 20 seem unreliable in that they do not reset the connection above 20secs and after the first keepalive, the device will reset at (TRUNC((KA+1)/2)*2)*3+20 before the first keepalive, add 1 if KA<30, add 15 if KA<120, else add 105 actually, about a second earlier. After the first missed KA, the next will be about a second early not valid for other devices Set First (s) Then (s) Packets (#) Reset (s) 20 21 20 3 20 25 27 26 3 20 26 27 26 3 20 29 31 30 3 20 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 197 30 45 30 3 20 60 75 60 3 20 90 105 90 3 20 119 135 120 3 20 120 225 120 3 20 600 705 600 3 20 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 198 Skinny device stuff Collection of notes on weird device stuff. 7937 Conference Phone firmware appears to have 10 speedial buttons hardcoded into the firmware. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 199 Asterisk Configuration The top-level page for all things related to Asterisk configuration Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 200 General Configuration Information The top-level page for general (typical) Asterisk configuration information. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 201 Configuration Parser Introduction The Asterisk configuration parser in the 1.2 version and beyond series has been improved in a number of ways. In addition to the realtime architecture, we now have the ability to create templates in configuration files, and use these as templates when we configure phones, voicemail accounts and queues. These changes are general to the configuration parser, and works in all configuration files. General syntax Asterisk configuration files are defined as follows: [section] label = value label2 = value In some files, (e.g. mgcp.conf, dahdi.conf and agents.conf), the syntax is a bit different. In these files the syntax is as follows: [section] label1 = value1 label2 = value2 object => name label3 = value3 label2 = value4 object2 => name2 In this syntax, we create objects with the settings defined above the object creation. Note that settings are inherited from the top, so in the example above object2 has inherited the setting for "label1" from the first object. For template configurations, the syntax for defining a section is changed to: [section](options) label = value The options field is used to define templates, refer to templates and hide templates. Any object can be used as a template. No whitespace is allowed between the closing "]" and the parenthesis "(". Comments All lines that starts with semi-colon ";" is treated as comments and is not parsed. The ";" is a marker for a multi-line comment. Everything after that marker will be treated as a comment until the end-marker " ;" is found. Parsing begins directly after the end-marker. ;This is a comment label = value ;-- This is a comment -; ;- Comment --; exten=> 1000,1,dial(SIP/lisa) Including other files In all of the configuration files, you may include the content of another file with the #include statement. The content of the other file will be included at the row that the #include statement occurred. #include myusers.conf You may also include the output of a program with the #exec directive, if you enable it in asterisk.conf Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 202 In asterisk.conf, add the execincludes = yes statement in the options section: [options] execincludes=yes The exec directive is used like this: #exec /usr/local/bin/myasteriskconfigurator.sh Adding to an existing section [section] label = value [section](+) label2 = value2 In this case, the plus sign indicates that the second section (with the same name) is an addition to the first section. The second section can be in another file (by using the #include statement). If the section name referred to before the plus is missing, the configuration will fail to load. Defining a template-only section [section](!) label = value The exclamation mark indicates to the config parser that this is a only a template and should not itself be used by the Asterisk module for configuration. The section can be inherited by other sections (see section "Using templates" below) but is not used by itself. Using templates (or other configuration sections) [section](name[,name]) label = value The name within the parenthesis refers to other sections, either templates or standard sections. The referred sections are included before the configuration engine parses the local settings within the section as though their entire contents (and anything they were previously based upon) were included in the new section. For example consider the following: [foo] disallow=all allow=ulaw allow=alaw [bar] allow=gsm allow=g729 permit=192.168.2.1 [baz](foo,bar) type=friend permit=192.168.3.1 context=incoming host=bnm The [baz] section will be processed as though it had been written in the following way: Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 203 [baz] disallow=all allow=ulaw allow=alaw allow=gsm allow=g729 permit=192.168.2.1 type=friend permit=192.168.3.1 context=incoming host=bnm It should also be noted that there are no guaranteed overriding semantics, meaning that if you define something in one template, you should not expect to be able to override it by defining it again in another template. Additional Examples (in top-level sip.conf) [defaults] type=friend nat=yes qualify=on dtmfmode=rfc2833 disallow=all allow=alaw #include accounts/*/sip.conf (in accounts/customer1/sip.conf) [def-customer1](!,defaults) secret=this_is_not_secret context=from-customer1 callerid=Customer 1 <300> accountcode=0001 [phone1](def-customer1) mailbox=phone1@customer1 [phone2](def-customer1) mailbox=phone2@customer1 This example defines two phones - phone1 and phone2 with settings inherited from "def-customer1". The "def-customer1" is a template that inherits from "defaults", which also is a template. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 204 The asterisk.conf file Asterisk Main Configuration File Below is a sample of the main Asterisk configuration file, asterisk.conf. Note that this file is not provided in sample form, because the Makefile creates it when needed and does not touch it when it already exists. [directories] ; Make sure these directories have the right permissions if not ; running Asterisk as root ; Where the configuration files (except for this one) are located astetcdir => /etc/asterisk ; Where the Asterisk loadable modules are located astmoddir => /usr/lib/asterisk/modules ; Where additional 'library' elements (scripts, etc.) are located astvarlibdir => /var/lib/asterisk ; Where AGI scripts/programs are located astagidir => /var/lib/asterisk/agi-bin ; Where spool directories are located ; Voicemail, monitor, dictation and other apps will create files here ; and outgoing call files (used with pbx_spool) must be placed here astspooldir => /var/spool/asterisk ; Where the Asterisk process ID (pid) file should be created astrundir => /var/run/asterisk ; Where the Asterisk log files should be created astlogdir => /var/log/asterisk [options] ;Under "options" you can enter configuration options ;that you also can set with command line options ; Verbosity level for logging (-v) verbose = 0 ; Debug: "No" or value (1-4) debug = 3 ; Background execution disabled (-f) nofork=yes | no ; Always background, even with -v or -d (-F) alwaysfork=yes | no ; Console mode (-c) console= yes | no ; Execute with high priority (-p) highpriority = yes | no ; Initialize crypto at startup (-i) initcrypto = yes | no ; Disable ANSI colors (-n) nocolor = yes | no Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 205 ; Dump core on failure (-g) dumpcore = yes | no ; Run quietly (-q) quiet = yes | no ; Force timestamping in CLI verbose output (-T) timestamp = yes | no ; User to run asterisk as (-U) NOTE: will require changes to ; directory and device permissions runuser = asterisk ; Group to run asterisk as (-G) rungroup = asterisk ; Enable internal timing support (-I) internal_timing = yes | no ; Language Options documentation_language = en | es | ru ; These options have no command line equivalent ; Cache record() files in another directory until completion cache_record_files = yes | no record_cache_dir = ; Build transcode paths via SLINEAR transcode_via_sln = yes | no ; send SLINEAR silence while channel is being recorded transmit_silence_during_record = yes | no ; The maximum load average we accept calls for maxload = 1.0 ; The maximum number of concurrent calls you want to allow maxcalls = 255 ; Stop accepting calls when free memory falls below this amount specified in MB minmemfree = 256 ; Allow #exec entries in configuration files execincludes = yes | no ; Don't over-inform the Asterisk sysadm, he's a guru dontwarn = yes | no ; System name. Used to prefix CDR uniqueid and to fill \${SYSTEMNAME} systemname = ; Should language code be last component of sound file name or first? ; when off, sound files are searched as // ; when on, sound files are search as // ; (only affects relative paths for sound files) languageprefix = yes | no Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 206 ; Locking mode for voicemail ; - lockfile: default, for normal use ; - flock: for where the lockfile locking method doesn't work ; eh. on SMB/CIFS mounts lockmode = lockfile | flock ; ; ; ; ; Entity ID. This is in the form of a MAC address. It should be universally unique. It must be unique between servers communicating with a protocol that uses this value. The only thing that uses this currently is DUNDi, but other things will use it in the future. entityid=00:11:22:33:44:55 [files] ; Changing the following lines may compromise your security ; Asterisk.ctl is the pipe that is used to connect the remote CLI ; (asterisk -r) to Asterisk. Changing these settings change the ; permissions and ownership of this file. ; The file is created when Asterisk starts, in the "astrundir" above. ;astctlpermissions = 0660 ;astctlowner = root Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 207 ;astctlgroup = asterisk ;astctl = asterisk.ctl Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 208 CLI Prompt Changing the CLI Prompt The CLI prompt is set with the ASTERISK_PROMPT UNIX environment variable that you set from the Unix shell before starting Asterisk You may include the following variables, that will be replaced by the current value by Asterisk: %d - Date (year-month-date) %s - Asterisk system name (from asterisk.conf) %h - Full hostname %H - Short hostname %t - Time %u - Username %g - Groupname %% - Percent sign %# - '#' if Asterisk is run in console mode, '' if running as remote console %Cn[;n] - Change terminal foreground (and optional background) color to specified A full list of colors may be found in include/asterisk/term.h On systems which implement getloadavg(3), you may also use: %l1 - Load average over past minute %l2 - Load average over past 5 minutes %l3 - Load average over past 15 minutes Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 209 The Asterisk Dialplan The Asterisk dialplan The Asterisk dialplan is divided into contexts. A context is simply a group of extensions. For each "line" that should be able to be called, an extension must be added to a context. Then, you configure the calling "line" to have access to this context. If you change the dialplan, you can use the Asterisk CLI command "dialplan reload" to load the new dialplan without disrupting service in your PBX. Extensions are routed according to priority and may be based on any set of characters (a-z), digits, #, and *. Please note that when matching a pattern, "N", "X", and "Z" are interpreted as classes of digits. For each extension, several actions may be listed and must be given a unique priority. When each action completes, the call continues at the next priority (except for some modules which use explicitly GOTO's). Extensions frequently have data they pass to the executing application (most frequently a string). You can see the available dialplan applications by entering the "core show applications" command in the CLI. In this version of Asterisk, dialplan functions are added. These can be used as arguments to any application. For a list of the installed functions in your Asterisk, use the "core show functions" command. Example dialplan The example dial plan, in the configs/extensions.conf.sample file is installed as extensions.conf if you run "make samples" after installation of Asterisk. This file includes many more instructions and examples than this file, so it's worthwhile to read it. Special extensions There are some extensions with important meanings: s - What to do when an extension context is entered (unless overridden by the low level channel interface) This is used in macros, and some special cases. "s" is not a generic catch-all wildcard extension. i - What to do if an invalid extension is entered h - The hangup extension, executed at hangup t - What to do if nothing is entered in the requisite amount of time. T - This is the extension that is executed when the 'absolute' timeout is reached. See "core show function TIMEOUT" for more information on setting timeouts. e - This extension will substitute as a catchall for any of the 'i', 't', or 'T' extensions, if any of them do not exist and catching the error in a single routine is desired. The function EXCEPTION may be used to query the type of exception or the location where it occurred. And finally, the extension context "default" is used when either a) an extension context is deleted while an extension is in use, or b) a specific starting extension handler has not been defined (unless overridden by the low level channel interface). Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 210 IP Quality of Service Introduction Asterisk supports different QoS settings at the application level for various protocols on both signaling and media. The Type of Service (TOS) byte can be set on outgoing IP packets for various protocols. The TOS byte is used by the network to provide some level of Quality of Service (QoS) even if the network is congested with other traffic. Asterisk running on Linux can also set 802.1p CoS marks in VLAN packets for the VoIP protocols it uses. This is useful when working in a switched environment. In fact Asterisk only set priority for Linux socket. For mapping this priority and VLAN CoS mark you need to use this command: vconfig set_egress_map [vlan-device] [skb-priority] [vlan-qos] The table below shows all VoIP channel drivers and other Asterisk modules that support QoS settings for network traffic. It also shows the type(s) of traffic for which each module can support setting QoS settings. Table 2.1: Channel Driver QoS Settings Signaling Audio Video Text chan_sip + + + + chan_skinny + + + chan_mgcp + + chan_unistm + + chan_h323 + chan_iax2 + chan_pjsip + + + Signaling Audio Video Table 2.2: Other ToS Settings dundi.conf + (tos setting) iaxprov.conf + (tos setting) Text IP TOS values The allowable values for any of the tos parameters are: CS0, CS1, CS2, CS3, CS4, CS5, CS6, CS7, AF11, AF12, AF13, AF21, AF22, AF23, AF31, AF32, AF33, AF41, AF42, AF43 and ef (expedited forwarding),* The tos parameters also take numeric values.* Note that on a Linux system, Asterisk must be compiled with libcap in order to use the ef tos setting if Asterisk is not run as root. The lowdelay, throughput, reliability, mincost, and none values have been removed in current releases. 802.1p CoS values Because 802.1p uses 3 bits of the VLAN header, this parameter can take integer values from 0 to 7. Recommended values The recommended values shown below are also included in sample configuration files: Table 2.3: Recommended QoS Settings Signaling tos cos cs3 3 Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 211 Audio ef 5 Video af41 4 Text af41 3 Other ef IAX2 In iax.conf, there is a "tos" parameter that sets the global default TOS for IAX packets generated by chan_iax2. Since IAX connections combine signalling, audio, and video into one UDP stream, it is not possible to set the TOS separately for the different types of traffic. In iaxprov.conf, there is a "tos" parameter that tells the IAXy what TOS to set on packets it generates. As with the parameter in iax.conf, IAX packets generated by an IAXy cannot have different TOS settings based upon the type of packet. However different IAXy devices can have different TOS settings. SIP In sip.conf, there are four parameters that control the TOS settings: "tos_sip", "tos_audio", "tos_video" and "tos_text". tos_sip controls what TOS SIP call signaling packets are set to. tos_audio, tos_video and tos_text control what TOS values are used for RTP audio, video, and text packets, respectively. There are four parameters to control 802.1p CoS: "cos_sip", "cos_audio", "cos_video" and "cos_text". The behavior of these parameters is the same as for the SIP TOS settings described above. Other RTP channels chan_mgcp, chan_h323, chan_skinny and chan_unistim also support TOS and CoS via setting tos and cos parameters in their corresponding configuration files. Naming style and behavior are the same as for chan_sip. Reference IEEE 802.1Q Standard: http://standards.ieee.org/getieee802/download/802.1Q-1998.pdfRelated protocols: IEEE 802.3, 802.2, 802.1D, 802.1Q RFC 2474 - "Definition of the Differentiated Services Field (DS field) in the IPv4 and IPv6 Headers", Nichols, K., et al, December 1998. IANA Assignments, DSCP registry Differentiated Services Field Codepoints http://www.iana.org/assignments/dscp-registry To get the most out of setting the TOS on packets generated by Asterisk, you will need to ensure that your network handles packets with a TOS properly. For Cisco devices, see the previously mentioned "Enterprise QoS Solution Reference Network Design Guide". For Linux systems see the "Linux Advanced Routing & Traffic Control HOWTO" at http://www.lartc.org/. For more information on Quality of Service for VoIP networks see the "Enterprise QoS Solution Reference Network Design Guide" version 3.3 from Cisco at: http://www.cisco.com/application/pdf/en/us/guest/netsol/ns432/c649/ccmigration_09186a008049b062.pdf Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 212 MP3 Support MP3 Music On Hold Use of the mpg123 for your music on hold is no longer recommended and is now officially deprecated. You should now use one of the native formats for your music on hold selections. However, if you still need to use mp3 as your music on hold format, a format driver for reading MP3 audio files is available in the asterisk-addons SVN repository on svn.digium.com or in the asterisk-addons release at http://downloads.asterisk.org/pub/telephony/asterisk/. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 213 ICES The advent of icecast into Asterisk allows you to do neat things like have a caller stream right into an ice-cast stream as well as using chan_local to place things like conferences, music on hold, etc. into the stream. You'll need to specify a config file for the ices encoder. An example is included in contrib/asterisk-ices.xml. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 214 Database Support Configuration Top-level page for information about Database support. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 215 Realtime Database Configuration Introduction Two modes: Static and Realtime Realtime SIP friends Realtime H.323 friends New function in the dial plan: The Realtime Switch Capabilities Configuration in extconfig.conf Limitations FreeTDS supported with connection pooling Notes on use of the sipregs family Introduction The Asterisk Realtime Architecture is a new set of drivers and functions implemented in Asterisk. The benefits of this architecture are many, both from a code management standpoint and from an installation perspective. The ARA is designed to be independent of storage. Currently, most drivers are based on SQL, but the architecture should be able to handle other storage methods in the future, like LDAP. The main benefit comes in the database support. In Asterisk v1.0 some functions supported MySQL database, some PostgreSQL and other ODBC. With the ARA, we have a unified database interface internally in Asterisk, so if one function supports database integration, all databases that has a realtime driver will be supported in that function. Currently there are three realtime database drivers: 1. ODBC: Support for UnixODBC, integrated into Asterisk The UnixODBC subsystem supports many different databases, please check www.unixodbc.org for more information. 2. MySQL: Native support for MySQL, integrated into Asterisk 3. PostgreSQL: Native support for Postgres, integrated into Asterisk Two modes: Static and Realtime The ARA realtime mode is used to dynamically load and update objects. This mode is used in the SIP and IAX2 channels, as well as in the voicemail system. For SIP and IAX2 this is similar to the v1.0 MYSQL_FRIENDS functionality. With the ARA, we now support many more databases for dynamic configuration of phones. The ARA static mode is used to load configuration files. For the Asterisk modules that read configurations, there's no difference between a static file in the file system, like extensions.conf, and a configuration loaded from a database. You just have to always make sure the var_metric values are properly set and ordered as you expect in your database server if you're using the static mode with ARA (either sequentially or with the same var_metric value for everybody). If you have an option that depends on another one in a given configuration file (i.e, 'musiconhold' depending on 'agent' from agents.conf) but their var_metric are not sequential you'll probably get default values being assigned for those options instead of the desired ones. You can still use the same var_metric for all entries in your DB, just make sure the entries are recorded in an order that does not break the option dependency. That doesn't happen when you use a static file in the file system. Although this might be interpreted as a bug or limitation, it is not. To use static realtime with certain core configuration files (e.g. features.conf, cdr.conf, cel.conf, indications.conf, etc.) the realtime backend you wish to use must be preloaded in modules.conf. [modules] preload => res_odbc.so preload => res_config_odbc.so Realtime SIP friends The SIP realtime objects are users and peers that are loaded in memory when needed, then deleted. This means that Asterisk currently can't handle voicemail notification and NAT keepalives for these peers. Other than that, most of the functionality works the same way for realtime friends as for the ones in static configuration. With caching, the device stays in memory for a specified time. More information about this is to be found in the sip.conf sample file. If you specify a separate family called "sipregs" SIP registration data will be stored in that table and not in the "sippeers" table. Realtime H.323 friends Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 216 Like SIP realtime friends, H.323 friends also can be configured using dynamic realtime objects. New function in the dial plan: The Realtime Switch The realtime switch is more than a port of functionality in v1.0 to the new architecture, this is a new feature of Asterisk based on the ARA. The realtime switch lets your Asterisk server do database lookups of extensions in realtime from your dial plan. You can have many Asterisk servers sharing a dynamically updated dial plan in real time with this solution. Note that this switch does NOT support Caller ID matching, only extension name or pattern matching. Capabilities The realtime Architecture lets you store all of your configuration in databases and reload it whenever you want. You can force a reload over the AMI, Asterisk Manager Interface or by calling Asterisk from a shell script with asterisk -rx "reload" You may also dynamically add SIP and IAX devices and extensions and making them available without a reload, by using the realtime objects and the realtime switch. Configuration in extconfig.conf You configure the ARA in extconfig.conf (yes, it's a strange name, but is was defined in the early days of the realtime architecture and kind of stuck). The part of Asterisk that connects to the ARA use a well defined family name to find the proper database driver. The syntax is easy: => ,.conf class name>[,] The options following the realtime driver identified depends on the driver. Defined well-known family names are: sippeers, sipusers - SIP peers and users sipregs - SIP registrations iaxpeers, iaxusers - IAX2 peers and users voicemail - Voicemail accounts extensions - Realtime extensions (switch) meetme - MeetMe conference rooms queues - Queues queue_members - Queue members musiconhold - Music On Hold classes queue_log - Queue logging Voicemail storage with the support of ODBC described in ODBC Voicemail Storage. Limitations Currently, realtime extensions do not support realtime hints. There is a workaround available by using func_odbc. See the sample func_odbc.conf for more information. FreeTDS supported with connection pooling In order to use a FreeTDS-based database with realtime, you need to turn connection pooling on in res_odbc.conf. This is due to a limitation within the FreeTDS protocol itself. Please note that this includes databases such as MS SQL Server and Sybase. This support is new in the current release. You may notice a performance issue under high load using UnixODBC. The UnixODBC driver supports threading but you must specifically enable threading within the UnixODBC configuration file like below for each engine: Threading = 2 This will enable the driver to service many requests at a time, rather than serially. Notes on use of the sipregs family The community provided some additional recommendations on the JIRA issue ASTERISK-21315: It is a good idea to avoid using sipregs altogether by NOT enabling it in extconfig. Using a writable sipusers table should be enough. If Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 217 you cannot write to your base sipusers table because it is readonly, you could consider making a separate sipusers view that joins the readonly table with a writable sipregs table. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 218 FreeTDS The cdr_tds module now works with most modern release versions of FreeTDS (from at least 0.60 through 0.82). Although versions of FreeTDS prior to 0.82 will work, we recommend using the latest available version for performance and stability reasons. *The latest release of FreeTDS is available from http://www.freetds.org/* Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 219 SIP Realtime, MySQL table structure Here is the table structure used by MySQL for Realtime SIP friends # # Table structure for table `sipfriends` # CREATE TABLE IF NOT EXISTS `sipfriends` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL, `ipaddr` varchar(15) DEFAULT NULL, `port` int(5) DEFAULT NULL, `regseconds` int(11) DEFAULT NULL, `defaultuser` varchar(10) DEFAULT NULL, `fullcontact` varchar(35) DEFAULT NULL, `regserver` varchar(20) DEFAULT NULL, `useragent` varchar(20) DEFAULT NULL, `lastms` int(11) DEFAULT NULL, `host` varchar(40) DEFAULT NULL, `type` enum('friend','user','peer') DEFAULT NULL, `context` varchar(40) DEFAULT NULL, `permit` varchar(40) DEFAULT NULL, `deny` varchar(40) DEFAULT NULL, `secret` varchar(40) DEFAULT NULL, `md5secret` varchar(40) DEFAULT NULL, `remotesecret` varchar(40) DEFAULT NULL, `transport` enum('udp','tcp','udp,tcp','tcp,udp') DEFAULT NULL, `dtmfmode` enum('rfc2833','info','shortinfo','inband','auto') DEFAULT NULL, `directmedia` enum('yes','no','nonat','update') DEFAULT NULL, `nat` enum('yes','no','never','route') DEFAULT NULL, `callgroup` varchar(40) DEFAULT NULL, `pickupgroup` varchar(40) DEFAULT NULL, `language` varchar(40) DEFAULT NULL, `allow` varchar(40) DEFAULT NULL, `disallow` varchar(40) DEFAULT NULL, `insecure` varchar(40) DEFAULT NULL, `trustrpid` enum('yes','no') DEFAULT NULL, `progressinband` enum('yes','no','never') DEFAULT NULL, `promiscredir` enum('yes','no') DEFAULT NULL, `useclientcode` enum('yes','no') DEFAULT NULL, `accountcode` varchar(40) DEFAULT NULL, `setvar` varchar(40) DEFAULT NULL, `callerid` varchar(40) DEFAULT NULL, `amaflags` varchar(40) DEFAULT NULL, `callcounter` enum('yes','no') DEFAULT NULL, `busylevel` int(11) DEFAULT NULL, `allowoverlap` enum('yes','no') DEFAULT NULL, `allowsubscribe` enum('yes','no') DEFAULT NULL, `videosupport` enum('yes','no') DEFAULT NULL, `maxcallbitrate` int(11) DEFAULT NULL, `rfc2833compensate` enum('yes','no') DEFAULT NULL, `mailbox` varchar(40) DEFAULT NULL, `session-timers` enum('accept','refuse','originate') DEFAULT NULL, `session-expires` int(11) DEFAULT NULL, `session-minse` int(11) DEFAULT NULL, `session-refresher` enum('uac','uas') DEFAULT NULL, `t38pt_usertpsource` varchar(40) DEFAULT NULL, `regexten` varchar(40) DEFAULT NULL, `fromdomain` varchar(40) DEFAULT NULL, `fromuser` varchar(40) DEFAULT NULL, `qualify` varchar(40) DEFAULT NULL, `defaultip` varchar(40) DEFAULT NULL, `rtptimeout` int(11) DEFAULT NULL, `rtpholdtimeout` int(11) DEFAULT NULL, `sendrpid` enum('yes','no') DEFAULT NULL, `outboundproxy` varchar(40) DEFAULT NULL, `callbackextension` varchar(40) DEFAULT NULL, `registertrying` enum('yes','no') DEFAULT NULL, `timert1` int(11) DEFAULT NULL, `timerb` int(11) DEFAULT NULL, `qualifyfreq` int(11) DEFAULT NULL, `constantssrc` enum('yes','no') DEFAULT NULL, `contactpermit` varchar(40) DEFAULT NULL, `contactdeny` varchar(40) DEFAULT NULL, `usereqphone` enum('yes','no') DEFAULT NULL, `textsupport` enum('yes','no') DEFAULT NULL, `faxdetect` enum('yes','no') DEFAULT NULL, `buggymwi` enum('yes','no') DEFAULT NULL, `auth` varchar(40) DEFAULT NULL, `fullname` varchar(40) DEFAULT NULL, `trunkname` varchar(40) DEFAULT NULL, `cid_number` varchar(40) DEFAULT NULL, `callingpres` enum('allowed_not_screened','allowed_passed_screen','allowed_failed_screen','allowed','prohib_not_screened','prohib_passed_screen ','prohib_failed_screen','prohib') DEFAULT NULL, `mohinterpret` varchar(40) DEFAULT NULL, Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 220 `mohsuggest` varchar(40) DEFAULT NULL, `parkinglot` varchar(40) DEFAULT NULL, `hasvoicemail` enum('yes','no') DEFAULT NULL, `subscribemwi` enum('yes','no') DEFAULT NULL, `vmexten` varchar(40) DEFAULT NULL, `autoframing` enum('yes','no') DEFAULT NULL, `rtpkeepalive` int(11) DEFAULT NULL, `call-limit` int(11) DEFAULT NULL, `g726nonstandard` enum('yes','no') DEFAULT NULL, `ignoresdpversion` enum('yes','no') DEFAULT NULL, `allowtransfer` enum('yes','no') DEFAULT NULL, `dynamic` enum('yes','no') DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`), KEY `ipaddr` (`ipaddr`,`port`), Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 221 KEY `host` (`host`,`port`) ) ENGINE=MyISAM; Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 222 Privacy Configuration So, you want to avoid talking to pesky telemarketers/charity seekers/poll takers/magazine renewers/etc? Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 223 FTC Don't Call List The FTC "Don't call" database, this alone will reduce your telemarketing call volume considerably. (see: https://www.donotcall.gov/default.aspx ) But, this list won't protect from the Charities, previous business relationships, etc. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 224 Fighting Autodialers Zapateller detects if callerid is present, and if not, plays the da-da-da tones that immediately precede messages like, "I'm sorry, the number you have called is no longer in service." Most humans, even those with unlisted/callerid-blocked numbers, will not immediately slam the handset down on the hook the moment they hear the three tones. But autodialers seem pretty quick to do this. I just counted 40 hangups in Zapateller over the last year in my CDR's. So, that is possibly 40 different telemarketers/charities that have hopefully slashed my back-waters, out-of-the-way, humble home phone number from their lists. I highly advise Zapateller for those seeking the nirvana of "privacy". Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 225 Fighting Empty Caller ID A considerable percentage of the calls you don't want, come from sites that do not provide CallerID. Null callerid's are a fact of life, and could be a friend with an unlisted number, or some charity looking for a handout. The PrivacyManager application can help here. It will ask the caller to enter a 10-digit phone number. They get 3 tries(configurable), and this is configurable, with control being passed to next priority where you can check the channelvariable PRIVACYMGRSTATUS. If the callerid was valid this variable will have the value SUCCESS, otherwise it will have the value FAILED. PrivacyManager can't guarantee that the number they supply is any good, tho, as there is no way to find out, short of hanging up and calling them back. But some answers are obviously wrong. For instance, it seems a common practice for telemarketers to use your own number instead of giving you theirs. A simple test can detect this. More advanced tests would be to look for 555 numbers, numbers that count up or down, numbers of all the same digit, etc. PrivacyManager can be told about a context where you can have patterns that describe valid phone numbers. If none of the patterns match the input, it will be considered a non-valid phonenumber and the user can try again until the retry counter is reached. This helps in resolving the issues stated in the previous paragraph. My logs show that 39 have hung up in the PrivacyManager script over the last year. (Note: Demanding all unlisted incoming callers to enter their CID may not always be appropriate for all users. Another option might be to use call screening. See below.) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 226 Using Welcome Menus for Privacy Experience has shown that simply presenting incoming callers with a set of options, no matter how simple, will deter them from calling you. In the vast majority of situations, a telemarketer will simply hang up rather than make a choice and press a key. This will also immediately foil all autodialers that simply belch a message in your ear and hang up. Example usage of Zapateller and PrivacyManager [homeline] exten => s,1,Answer exten => s,2,SetVar,repeatcount=0 exten => s,3,Zapateller,nocallerid exten => s,4,PrivacyManager ;; do this if they don't enter a number to Privacy Manager exten => s,5,GotoIf($[ "${PRIVACYMGRSTATUS}" = "FAILED" ]?s,105) exten => s,6,GotoIf($[ "${CALLERID(num)}" = "7773334444" & "${CALLERID(name)}" : "Privacy Manager" ]?callerid-liar,s,1:s,7) exten => s,7,Dial(SIP/yourphone) exten => s,105,Background(tt-allbusy) exten => s,106,Background(tt-somethingwrong) exten => s,107,Background(tt-monkeysintro) exten => s,108,Background(tt-monkeys) exten => s,109,Background(tt-weasels) exten => s,110,Hangup I suggest using Zapateller at the beginning of the context, before anything else, on incoming calls.This can be followed by the PrivacyManager App. Make sure, if you do the PrivacyManager app, that you take care of the error condition! or their non-compliance will be rewarded with access to the system. In the above, if they can't enter a 10-digit number in 3 tries, they get the humorous "I'm sorry, but all household members are currently helping other telemarketers...", "something is terribly wrong", "monkeys have carried them away...", various loud monkey screechings, "weasels have...", and a hangup. There are plenty of other paths to my torture scripts, I wanted to have some fun. In nearly all cases now, the telemarketers/charity-seekers that usually get thru to my main intro, hang up. I guess they can see it's pointless, or the average telemarketer/charity-seeker is instructed not to enter options when encountering such systems. Don't know. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 227 Making life difficult for telemarketers I have developed an elaborate script to torture Telemarketers, and entertain friends. While mostly those that call in and traverse my teletorture scripts are those we know, and are doing so out of curiosity, there have been these others from Jan 1st,2004 thru June 1st, 2004: (the numbers may or may not be correct.) 603890zzzz - hung up telemarket options. "Integrated Sale" - called a couple times. hung up in telemarket options "UNITED STATES GOV" - maybe a military recruiter, trying to lure one of my sons. 800349zzzz - hung up in charity intro 800349zzzz - hung up in charity choices, intro, about the only one who actually travelled to the bitter bottom of the scripts! 216377zzzz - hung up the magazine section 626757zzzz = "LIR " (pronounced "Liar"?) hung up in telemarket intro, then choices 757821zzzz - hung up in new magazine subscription options. That averages out to maybe 1 a month. That puts into question whether the ratio of the amount of labor it took to make the scripts versus the benefits of lower call volumes was worth it, but, well, I had fun, so what the heck. But, that's about it. Not a whole lot. But I haven't had to say "NO" or "GO AWAY" to any of these folks for about a year now ...! Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 228 Using Call Screening Another option is to use call screening in the Dial command. It has two main privacy modes, one that remembers the CID of the caller, and how the callee wants the call handled, and the other, which does not have a "memory". Turning on these modes in the dial command results in this sequence of events, when someone calls you at an extension: The caller calls the Asterisk system, and at some point, selects an option or enters an extension number that would dial your extension. Before ringing your extension, the caller is asked to supply an introduction. The application asks them: "After the tone, say your name". They are allowed 4 seconds of introduction. After that, they are told "Hang on, we will attempt to connect you to your party. Depending on your dial options, they will hear ringing indications, or get music on hold. I suggest music on hold. Your extension is then dialed. When (and if) you pick up, you are told that a caller presenting themselves as their recorded intro is played is calling, and you have options, like being connected, sending them to voicemail, torture, etc. You make your selection, and the call is handled as you chose. There are some variations, and these will be explained in due course. To use these options, set your Dial to something like: exten => 3,3,Dial(DAHDI/5r3&DAHDI/6r3,35,tmPA(beep)) or: exten => 3,3,Dial(DAHDI/5r3&DAHDI/6r3,35,tmP(something)A(beep)) or: exten => 3,3,Dial(DAHDI/5r3&DAHDI/6r3,35,tmpA(beep)) The 't' allows the dialed party to transfer the call using '#'. It's optional. The 'm' is for music on hold. I suggest it. Otherwise, the calling party gets to hear all the ringing, and lack thereof. It is generally better to use Music On Hold. Lots of folks hang up after the 3rd or 4th ring, and you might lose the call before you can enter an option! The 'P' option alone will database everything using the extension as a default 'tree'. To get multiple extensions sharing the same database, use P(some-shared-key). Also, if the same person has multiple extensions, use P(unique-id) on all their dial commands. Use little 'p' for screening. Every incoming call will include a prompt for the callee's choice. The A(beep), will generate a 'beep' that the callee will hear if they choose to talk to the caller. It's kind of a prompt to let the callee know that he has to say 'hi'. It's not required, but I find it helpful. When there is no CallerID, P and p options will always record an intro for the incoming caller. This intro will be stored temporarily in the /var/lib/asterisk/so unds/priv-callerintros dir, under the name NOCALLERID_extension channelname and will be erased after the callee decides what to do with the call. Of course, NOCALLERID is not stored in the database. All those with no CALLERID will be considered "Unknown". Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 229 Call Screening Options Two other options exist, that act as modifiers to the privacy options 'P' and 'p'. They are 'N' and 'n'. You can enter them as dialing options, but they only affect things if P or p are also in the options. 'N' says, "Only screen the call if no CallerID is present". So, if a callerID were supplied, it will come straight thru to your extension. 'n' says, "Don't save any introductions". Folks will be asked to supply an introduction ("At the tone, say your name") every time they call. Their introductions will be removed after the callee makes a choice on how to handle the call. Whether the P option or the p option is used, the incoming caller will have to supply their intro every time they call. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 230 Screening Calls with Recorded Introductions Philosophical Side Note The 'P' option stores the CALLERID in the database, along with the callee's choice of actions, as a convenience to the CALLEE, whereas introductions are stored and re-used for the convenience of the CALLER. Introductions Unless instructed to not save introductions (see the 'n' option above), the screening modes will save the recordings of the caller's names in the directory /var/lib/asterisk/sounds/priv-callerintros, if they have a CallerID. Just the 10-digit callerid numbers are used as filenames, with a ".gsm" at the end. Having these recordings around can be very useful, however... First of all, if a callerid is supplied, and a recorded intro for that number is already present, the caller is spared the inconvenience of having to supply their name, which shortens their call a bit. Next of all, these intros can be used in voicemail, played over loudspeakers, and perhaps other nifty things. For instance: exten => s,6,Set(PATH=/var/lib/asterisk/sounds/priv-callerintros) exten => s,7,System(/usr/bin/play ${PATH}/${CALLERID(num)}.gsm&,0) When a call comes in at the house, the above priority gets executed, and the callers intro is played over the phone systems speakers. This gives us a hint who is calling. (Note: the ,0 option at the end of the System command above, is a local mod I made to the System command. It forces a 0 result code to be returned, whether the play command successfully completed or not. Therefore, I don't have to ensure that the file exists or not. While I've turned this mod into the developers, it hasn't been incorporated yet. You might want to write an AGI or shell script to handle it a little more intelligently) And one other thing. You can easily supply your callers with an option to listen to, and re-record their introductions. Here's what I did in the home system's extensions.conf. (assume that a Goto(home-introduction,s,1) exists somewhere in your main menu as an option): [home-introduction] exten => s,1,Background(intro-options) ;; Script: ;; To hear your Introduction, dial 1. ;; to record a new introduction, dial 2. ;; to return to the main menu, dial 3. ;; to hear what this is all about, dial 4. exten => 1,1,Playback,priv-callerintros/${CALLERID(num)} exten => 1,2,Goto(s,1) exten => 2,1,Goto(home-introduction-record,s,1) exten => 3,1,Goto(homeline,s,7) exten => 4,1,Playback(intro-intro) ;; Script: ;; This may seem a little strange, but it really is a neat ;; thing, both for you and for us. I've taped a short introduction ;; for many of the folks who normally call us. Using the Caller ID ;; from each incoming call, the system plays the introduction ;; for that phone number over a speaker, just as the call comes in. ;; This helps the folks ;; here in the house more quickly determine who is calling. ;; and gets the right ones to gravitate to the phone. ;; You can listen to, and record a new intro for your phone number ;; using this menu. exten => 4,2,Goto(s,1) exten => t,1,Goto(s,1) exten => i,1,Background(invalid) exten => i,2,Goto(s,1) exten => o,1,Goto(s,1) [home-introduction-record] Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 231 exten => s,1,Background(intro-record-choices) ;; Script: ;; If you want some advice about recording your ;; introduction, dial 1. ;; otherwise, dial 2, and introduce yourself after ;; the beep. exten => 1,1,Playback(intro-record) ;; Your introduction should be short and sweet and crisp. ;; Your introduction will be limited to 4 seconds. ;; This is NOT meant to be a voice mail message, so ;; please, don't say anything about why you are calling. ;; After we are done making the recording, your introduction ;; will be saved for playback. ;; If you are the only person that would call from this number, ;; please state your name. Otherwise, state your business ;; or residence name instead. For instance, if you are ;; friend of the family, say, Olie McPherson, and both ;; you and your kids might call here a lot, you might ;; say: "This is the distinguished Olie McPherson Residence!" ;; If you are the only person calling, you might say this: ;; "This is the illustrious Kermit McFrog! Pick up the Phone, someone!! ;; If you are calling from a business, you might pronounce a more sedate introduction, like, ;; "Fritz from McDonalds calling.", or perhaps the more original introduction: ;; "John, from the Park County Morgue. You stab 'em, we slab 'em!". ;; Just one caution: the kids will hear what you record every time ;; you call. So watch your language! ;; I will begin recording after the tone. ;; When you are done, hit the # key. Gather your thoughts and get ;; ready. Remember, the # key will end the recording, and play back ;; your intro. Good Luck, and Thank you!" exten => 1,2,Goto(2,1) exten => 2,1,Background(intro-start) ;; OK, here we go! After the beep, please give your introduction. exten => 2,2,Background(beep) exten => 2,3,Record(priv-callerintros/${CALLERID(num)}:gsm,4) exten => 2,4,Background(priv-callerintros/${CALLERID(num)}) exten => 2,5,Goto(home-introduction,s,1) exten => t,1,Goto(s,1) exten => i,1,Background(invalid) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 232 exten => i,2,Goto(s,1) exten => o,1,Goto(s,1) In the above, you'd most likely reword the messages to your liking, and maybe do more advanced things with the 'error' conditions (i,o,t priorities), but I hope it conveys the idea. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 233 Asterisk Extension Language (AEL) Top-level page for all things AEL Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 234 Introduction to AEL AEL is a specialized language intended purely for describing Asterisk dial plans. The current version was written by Steve Murphy, and is a rewrite of the original version. This new version further extends AEL, and provides more flexible syntax, better error messages, and some missing functionality. AEL is really the merger of 4 different 'languages', or syntaxes: 1. The first and most obvious is the AEL syntax itself. A BNF is provided near the end of this document. 2. The second syntax is the Expression Syntax, which is normally handled by Asterisk extension engine, as expressions enclosed in $[...]. The right hand side of assignments are wrapped in $[ ... ] by AEL, and so are the if and while expressions, among others. 3. The third syntax is the Variable Reference Syntax, the stuff enclosed in ${..} curly braces. It's a bit more involved than just putting a variable name in there. You can include one of dozens of 'functions', and their arguments, and there are even some string manipulation notation in there. 4. The last syntax that underlies AEL, and is not used directly in AEL, is the Extension Language Syntax. The extension language is what you see in extensions.conf, and AEL compiles the higher level AEL language into extensions and priorities, and passes them via function calls into Asterisk. Embedded in this language is the Application/AGI commands, of which one application call per step, or priority can be made. You can think of this as a "macro assembler" language, that AEL will compile into. Any programmer of AEL should be familiar with its syntax, of course, as well as the Expression syntax, and the Variable syntax. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 235 AEL and Asterisk in a Nutshell Asterisk acts as a server. Devices involved in telephony, like DAHDI cards, or Voip phones, all indicate some context that should be activated in their behalf. See the config file formats for IAX, SIP, dahdi.conf, etc. They all help describe a device, and they all specify a context to activate when somebody picks up a phone, or a call comes in from the phone company, or a voip phone, etc. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 236 AEL about Contexts Contexts are a grouping of extensions. Contexts can also include other contexts. Think of it as a sort of merge operation at runtime, whereby the included context's extensions are added to the contexts making the inclusion. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 237 AEL about Extensions and priorities A Context contains zero or more Extensions. There are several predefined extensions. The "s" extension is the "start" extension, and when a device activates a context the "s" extension is the one that is going to be run. Other extensions are the timeout "t" extension, the invalid response, or "i" extension, and there's a "fax" extension. For instance, a normal call will activate the "s" extension, but an incoming FAX call will come into the "fax" extension, if it exists. (BTW, asterisk can tell it's a fax call by the little "beep" that the calling fax machine emits every so many seconds.). Extensions contain several priorities, which are individual instructions to perform. Some are as simple as setting a variable to a value. Others are as complex as initiating the Voicemail application, for instance. Priorities are executed in order. When the 's" extension completes, asterisk waits until the timeout for a response. If the response matches an extension's pattern in the context, then control is transferred to that extension. Usually the responses are tones emitted when a user presses a button on their phone. For instance, a context associated with a desk phone might not have any "s" extension. It just plays a dialtone until someone starts hitting numbers on the keypad, gather the number, find a matching extension, and begin executing it. That extension might Dial out over a connected telephone line for the user, and then connect the two lines together. The extensions can also contain "goto" or "jump" commands to skip to extensions in other contexts. Conditionals provide the ability to react to different stimuli, and there you have it. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 238 AEL about Macros Think of a macro as a combination of a context with one nameless extension, and a subroutine. It has arguments like a subroutine might. A macro call can be made within an extension, and the individual statements there are executed until it ends. At this point, execution returns to the next statement after the macro call. Macros can call other macros. And they work just like function calls. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 239 AEL about Applications Application calls, like "Dial()", or "Hangup()", or "Answer()", are available for users to use to accomplish the work of the dialplan. There are over 145 of them at the moment this was written, and the list grows as new needs and wants are uncovered. Some applications do fairly simple things, some provide amazingly complex services. Hopefully, the above objects will allow you do anything you need to in the Asterisk environment! Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 240 Getting Started with AEL The AEL parser (res_ael.so) is completely separate from the module that parses extensions.conf (pbx_config.so). To use AEL, the only thing that has to be done is the module res_ael.so must be loaded by Asterisk. This will be done automatically if using 'autoload=yes' in /etc/asterisk/modules.conf. When the module is loaded, it will look for 'extensions.ael' in /etc/asterisk/. extensions.conf and extensions.ael can be used in conjunction with each other if that is what is desired. Some users may want to keep extensions.conf for the features that are configured in the 'general' section of extensions.conf. To reload extensions.ael, the following command can be issued at the CLI: *CLI ael reload Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 241 AEL Debugging Right at this moment, the following commands are available, but do nothing: Enable AEL contexts debug *CLI> ael debug contexts Enable AEL macros debug *CLI> ael debug macros Enable AEL read debug *CLI> ael debug read Enable AEL tokens debug *CLI> ael debug tokens Disable AEL debug messages *CLI> ael no debug If things are going wrong in your dialplan, you can use the following facilities to debug your file: 1. The messages log in /var/log/asterisk. (from the checks done at load time). 2. The "show dialplan" command in asterisk 3. The standalone executable, "aelparse" built in the utils/ dir in the source. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 242 About "aelparse" You can use the "aelparse" program to check your extensions.ael file before feeding it to asterisk. Wouldn't it be nice to eliminate most errors before giving the file to asterisk? aelparse is compiled in the utils directory of the asterisk release. It isn't installed anywhere (yet). You can copy it to your favorite spot in your PATH. aelparse has two optional arguments: 1. -d - Override the normal location of the config file dir, (usually /etc/asterisk), and use the current directory instead as the config file dir. Aelparse will then expect to find the file "./extensions.ael" in the current directory, and any included files in the current directory as well. 2. -n - Don't show all the function calls to set priorities and contexts within asterisk. It will just show the errors and warnings from the parsing and semantic checking phases. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 243 General Notes about AEL Syntax Note that the syntax and style are now a little more free-form. The opening '' (curly-braces) do not have to be on the same line as the keyword that precedes them. Statements can be split across lines, as long as tokens are not broken by doing so. More than one statement can be included on a single line. Whatever you think is best! You can just as easily say, if(${x}=1) { NoOp(hello!); goto s,3; } else { NoOp(Goodbye!); goto s,12; } as you can say: if(${x}=1) { NoOp(hello!); goto s,3; } else { NoOp(Goodbye!); goto s,12; } or: if(${x}=1) { NoOp(hello!); goto s,3; } else { NoOp(Goodbye!); goto s,12; } or: if (${x}=1) { NoOp(hello!); goto s,3; } else { NoOp(Goodbye!); goto s,12; } Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 244 AEL Keywords The AEL keywords are case-sensitive. If an application name and a keyword overlap, there is probably good reason, and you should consider replacing the application call with an AEL statement. If you do not wish to do so, you can still use the application, by using a capitalized letter somewhere in its name. In the Asterisk extension language, application names are NOT case-sensitive. The following are keywords in the AEL language: abstract context macro globals ignorepat switch if ifTime else random goto jump local return break continue regexten hint for while case pattern default NOTE: the "default" keyword can be used as a context name, for those who would like to do so. catch switches eswitches includes Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 245 AEL Procedural Interface and Internals AEL first parses the extensions.ael file into a memory structure representing the file. The entire file is represented by a tree of "pval" structures linked together. This tree is then handed to the semantic check routine. Then the tree is handed to the compiler. After that, it is freed from memory. A program could be written that could build a tree of pval structures, and a pretty printing function is provided, that would dump the data to a file, or the tree could be handed to the compiler to merge the data into the asterisk dialplan. The modularity of the design offers several opportunities for developers to simplify apps to generate dialplan data. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 246 AEL version 2 BNF (hopefully, something close to bnf). First, some basic objects ----------------------- a lexical token consisting of characters matching this pattern: [-a-zA-Z0-9"_/.\<\>\*\+!$#\[\]][-a-zA-Z0-9"_/.!\*\+\<\>\{\}$#\[\]]* a concatenation of up to 3 s. all characters encountered until the character that follows the in the grammar. ------------------------ :== :== | :== | | | ';' :== | | | | | | | 'context' '{' '}' 'context' '{' '}' 'context' 'default' '{' '}' 'context' 'default' '{' '}' 'abstract' 'context' '{' '}' 'abstract' 'context' '{' '}' 'abstract' 'context' 'default' '{' '}' 'abstract' 'context' 'default' '{' '}' :== 'macro' '(' ')' '{' '}' | 'macro' '(' ')' '{' '}' | 'macro' '(' ')' '{' '}' | 'macro' '(' ')' '{' '}' :== 'globals' '{' '}' | 'globals' '{' '}' :== | :== '=' ';' :== | ',' :== | :== | | | | | '=' ';' | 'local' '=' ';' | ';' :== 'ignorepat' '=>' ';' :== '=>' | 'regexten' '=>' | 'hint' '(' ')' '=>' | 'regexten' 'hint' '(' ')' '=>' :== | :== 'if' '(' ')' :== 'random' '(' ')' :== 'ifTime' '(' ':' ':' '|' '|' '|' ')' | 'ifTime' '(' '|' '|' '|' ')' :== | | :== 'switch' '(' ')' '{' :== '{' '}' | '=' ';' | 'local' '=' ';' | 'goto' ';' | 'jump' ';' Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 247 | | | | | | | | | | | | | | | | | | | | | | | | ':' 'for' '(' ';' ';' ')' 'while' '(' ')' '}' '}' '&' macro_call ';' ';' '=' ';' 'break' ';' 'return' ';' 'continue' ';' 'else' 'else' 'else' ';' :== '|' '|' '|' 'default' '|' '|' ',' ',' ',' 'default' ',' ',' :== | | | | | :== | '(' ')' ',' ',' '@' ',' '@' '(' '@' '@' 'default' 'default' ')' :== '(' :== ')' | ')' :== | ',' | /* nothing */ | ',' /* nothing */ :== | :== 'case' ':' | 'default' ':' | 'pattern' ':' | 'case' ':' | 'default' ':' | 'pattern' ':' :== | :== | 'catch' '{' '}' :== 'switches' '{' '}' | 'switches' '{' '}' :== 'eswitches' '{' '}' | 'eswitches' '{' '}' :== ';' | ';' :== ';' | '|' ':' ':' '|' '|' '|' ';' | '|' '|' '|' '|' ';' | ';' | '|' ':' ':' '|' '|' '|' ';' | '|' '|' '|' '|' ';' :== | 'default' Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 248 :== 'includes' '{' '}' | 'includes' '{' '}' Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 249 AEL Example Usages Example usages of AEL Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 250 AEL Comments Comments begin with // and end with the end of the line. Comments are removed by the lexical scanner, and will not be recognized in places where it is busy gathering expressions to wrap in $[] , or inside application call argument lists. The safest place to put comments is after terminating semicolons, or on otherwise empty lines. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 251 AEL Context Contexts in AEL represent a set of extensions in the same way that they do in extensions.conf. context default { } A context can be declared to be "abstract", in which case, this declaration expresses the intent of the writer, that this context will only be included by another context, and not "stand on its own". The current effect of this keyword is to prevent "goto " statements from being checked. abstract context longdist { _1NXXNXXXXXX => NoOp(generic long distance dialing actions in the US); } Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 252 AEL Extensions To specify an extension in a context, the following syntax is used. If more than one application is be called in an extension, they can be listed in order inside of a block. context default { 1234 => Playback(tt-monkeys); 8000 => { NoOp(one); NoOp(two); NoOp(three); }; _5XXX => NoOp(it's a pattern!); } Two optional items have been added to the AEL syntax, that allow the specification of hints, and a keyword, regexten, that will force the numbering of priorities to start at 2. The ability to make extensions match by CID is preserved in AEL; just use '/' and the CID number in the specification. See below. context default { regexten _5XXX => NoOp(it's a pattern!); } context default { hint(Sip/1) _5XXX => NoOp(it's a pattern!); } context default { regexten hint(Sip/1) _5XXX => NoOp(it's a pattern!); } The regexten must come before the hint if they are both present. CID matching is done as with the extensions.conf file. Follow the extension name/number with a slash and the number to match against the Caller ID: context zoombo { 819/7079953345 => { NoOp(hello, 3345); } } In the above, the 819/7079953345 extension will only be matched if the CallerID is 7079953345, and the dialed number is 819. Hopefully you have another 819 extension defined for all those who wish 819, that are not so lucky as to have 7079953345 as their CallerID! Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 253 AEL Includes Contexts can be included in other contexts. All included contexts are listed within a single block. context default { includes { local; longdistance; international; } } Time-limited inclusions can be specified, as in extensions.conf format, with the fields described in the wiki page Asterisk cmd GotoIfTime. context default { includes { local; longdistance|16:00-23:59|mon-fri||; international; } } Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 254 AEL including other files You can include other files with the #include "filepath" construct. #include "/etc/asterisk/testfor.ael" An interesting property of the #include, is that you can use it almost anywhere in the .ael file. It is possible to include the contents of a file in a macro, context, or even extension. The #include does not have to occur at the beginning of a line. Included files can include other files, up to 50 levels deep. If the path provided in quotes is a relative path, the parser looks in the config file directory for the file (usually /etc/asterisk). Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 255 AEL Dialplan Switches Switches are listed in their own block within a context. For clues as to what these are used for, see Asterisk - dual servers, and Asterisk config extensions.conf. context default { switches { DUNDi/e164; IAX2/box5; }; eswitches { IAX2/context@${CURSERVER}; } } Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 256 AEL Ignorepat ignorepat can be used to instruct channel drivers to not cancel dialtone upon receipt of a particular pattern. The most commonly used example is '9'. context outgoing { ignorepat => 9; } Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 257 AEL Variables Variables in Asterisk do not have a type, so to define a variable, it just has to be specified with a value. Global variables are set in their own block. globals { CONSOLE=Console/dsp; TRUNK=DAHDI/g2; } Variables can be set within extensions as well. context foo { 555 => { x=5; y=blah; divexample=10/2 NoOp(x is ${x} and y is ${y} !); } } NOTE: AEL wraps the right hand side of an assignment with $[ ] to allow expressions to be used If this is unwanted, you can protect the right hand side from being wrapped by using the Set() application. Read the README.variables about the requirements and behavior of $[ ] expressions. NOTE: These things are wrapped up in a $[ ] expression: The while() test; the if() test; the middle expression in the for( x; y; z) statement (the y expression); Assignments - the right hand side, so a = b - Set(a=$[b]) Writing to a dialplan function is treated the same as writing to a variable. context blah { s => { CALLERID(name)=ChickenMan; NoOp(My name is ${CALLERID(name)} !); } } You can declare variables in Macros, as so: Macro myroutine(firstarg, secondarg) { Myvar=1; NoOp(Myvar is set to ${myvar}); } Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 258 AEL Local Variables In 1.2, and 1.4, ALL VARIABLES are CHANNEL variables, including the function arguments and associated ARG1, ARG2, etc variables. Sorry. In trunk (1.6 and higher), we have made all arguments local variables to a macro call. They will not affect channel variables of the same name. This includes the ARG1, ARG2, etc variables. Users can declare their own local variables by using the keyword 'local' before setting them to a value; Macro myroutine(firstarg, secondarg) { local Myvar=1; NoOp(Myvar is set to ${Myvar}, and firstarg is ${firstarg}, and secondarg is ${secondarg}); } In the above example, Myvar, firstarg, and secondarg are all local variables, and will not be visible to the calling code, be it an extension, or another Macro. If you need to make a local variable within the Set() application, you can do it this way: Macro myroutine(firstarg, secondarg) { Set(LOCAL(Myvar)=1); NoOp(Myvar is set to ${Myvar}, and firstarg is ${firstarg}, and secondarg is ${secondarg}); } Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 259 AEL Conditionals AEL supports if and switch statements, like AEL, but adds ifTime, and random. Unlike the original AEL, though, you do NOT need to put curly braces around a single statement in the "true" branch of an if(), the random(), or an ifTime() statement. The if(), ifTime(), and random() statements allow optional else clause. context conditional { _8XXX => { Dial(SIP/${EXTEN}); if ("${DIALSTATUS}" = "BUSY") { NoOp(yessir); Voicemail(${EXTEN},b); } else Voicemail(${EXTEN},u); ifTime (14:00-25:00,sat-sun,,) Voicemail(${EXTEN},b); else { Voicemail(${EXTEN},u); NoOp(hi, there!); } random(51) NoOp(This should appear 51% of the time); random( 60 ) { NoOp( This should appear 60% of the time ); } else { random(75) { NoOp( This should appear 30% of the time! ); } else { NoOp( This should appear 10% of the time! ); } } } _777X => { switch (${EXTEN}) { case 7771: NoOp(You called 7771!); break; case 7772: NoOp(You called 7772!); break; case 7773: NoOp(You called 7773!); // fall thrupattern 777[4-9]: NoOp(You called 777 something!); default: NoOp(In the default clause!); } } } Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 260 The conditional expression in if() statements (the "${DIALSTATUS}" = "BUSY" above) is wrapped by the compiler in $[] for evaluation. Neither the switch nor case values are wrapped in $[ ]; they can be constants, or ${var} type references only. AEL generates each case as a separate extension. case clauses with no terminating 'break', or 'goto', have a goto inserted, to the next clause, which creates a 'fall thru' effect. AEL introduces the ifTime keyword/statement, which works just like the if() statement, but the expression is a time value, exactly like that used by the application GotoIfTime(). See Asterisk cmd GotoIfTime The pattern statement makes sure the new extension that is created has an '_' preceding it to make sure asterisk recognizes the extension name as a pattern. Every character enclosed by the switch expression's parenthesis are included verbatim in the labels generated. So watch out for spaces! NEW: Previous to version 0.13, the random statement used the "Random()" application, which has been deprecated. It now uses the RAND() function instead, in the GotoIf application. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 261 AEL goto, jump, and labels This is an example of how to do a goto in AEL. context gotoexample { s => { begin: NoOp(Infinite Loop! yay!); Wait(1); goto begin; // go to label in same extension } 3 => { goto s, begin; // go to label in different extension } 4 => { goto gotoexample,s,begin; // overkill go to label in same context } } context gotoexample2 { s => { end: goto gotoexample,s,begin; // go to label in different context } } You can use the special label of "1" in the goto and jump statements. It means the "first" statement in the extension. I would not advise trying to use numeric labels other than "1" in goto's or jumps, nor would I advise declaring a "1" label anywhere! As a matter of fact, it would be bad form to declare a numeric label, and it might conflict with the priority numbers used internally by asterisk. The syntax of the jump statement is: jump extension[,priority][@context] If priority is absent, it defaults to "1". If context is not present, it is assumed to be the same as that which contains the "jump". context gotoexample { s => { begin: NoOp(Infinite Loop! yay!); Wait(1); jump s; // go to first extension in same extension } 3 => { jump s,begin; // go to label in different extension } 4 => { jump s,begin@gotoexample; // overkill go to label in same context } } context gotoexample2 { s => { end: jump s@gotoexample; // go to label in different context } } Goto labels follow the same requirements as the Goto() application, except the last value has to be a label. If the label does not exist, you will have run-time errors. If the label exists, but in a different extension, you have to specify both the extension name and label in the goto, as in: goto s,z; if the label is in a different context, you specify context,extension,label. There is a note about using goto's in a switch statement below... Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 262 AEL introduces the special label "1", which is the beginning context number for most extensions. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 263 AEL Macros A macro is defined in its own block like this. The arguments to the macro are specified with the name of the macro. They are then referred to by that same name. A catch block can be specified to catch special extensions. macro std-exten( ext , dev ) { Dial(${dev}/${ext},20); switch(${DIALSTATUS}) { case BUSY: Voicemail(${ext},b); break; default: Voicemail(${ext},u); } catch a { VoiceMailMain(${ext}); return; } } A macro is then called by preceding the macro name with an ampersand. Empty arguments can be passed simply with nothing between commas. context example { _5XXX => &std-exten(${EXTEN}, "IAX2"); _6XXX => &std-exten(, "IAX2"); _7XXX => &std-exten(${EXTEN},); _8XXX => &std-exten(,); } Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 264 AEL Loops AEL has implementations of 'for' and 'while' loops. context loops { 1 => { for (x=0; ${x} < 3; x=${x} + 1) { Verbose(x is ${x} !); } } 2 => { y=10; while (${y} >= 0) { Verbose(y is ${y} !); y=${y}-1; } } } NOTE: The conditional expression (the "${y} = 0" above) is wrapped in $[ ] so it can be evaluated. NOTE: The for loop test expression (the "$x 3" above) is wrapped in $[ ] so it can be evaluated. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 265 AEL Break, Continue, and Return Three keywords: 1. break 2. continue 3. return are included in the syntax to provide flow of control to loops, and switches. The break can be used in switches and loops, to jump to the end of the loop or switch. The continue can be used in loops (while and for) to immediately jump to the end of the loop. In the case of a for loop, the increment and test will then be performed. In the case of the while loop, the continue will jump to the test at the top of the loop. The return keyword will cause an immediate jump to the end of the context, or macro, and can be used anywhere. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 266 AEL Examples context demo { s => { Wait(1); Answer(); TIMEOUT(digit)=5; TIMEOUT(response)=10; restart: Background(demo-congrats); instructions: for (x=0; ${x} < 3; x=${x} + 1) { Background(demo-instruct); WaitExten(); } } 2 => { Background(demo-moreinfo); goto s,instructions; } 3 => { LANGUAGE()=fr; goto s,restart; } 500 => { Playback(demo-abouttotry); Dial(IAX2/guest@misery.digium.com); Playback(demo-nogo); goto s,instructions; } 600 => { Playback(demo-echotest); Echo(); Playback(demo-echodone); goto s,instructions; } # => { hangup: Playback(demo-thanks); Hangup(); } t => goto #,hangup; i => Playback(invalid); } Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 267 AEL Semantic Checks AEL, after parsing, but before compiling, traverses the dialplan tree, and makes several checks: Macro calls to non-existent macros. Macro calls to contexts. Macro calls with argument count not matching the definition. application call to macro. (missing the '&') application calls to "GotoIf", "GotoIfTime", "while", "endwhile", "Random", and "execIf", will generate a message to consider converting the call to AEL goto, while, etc. constructs. goto a label in an empty extension. goto a non-existent label, either a within-extension, within-context, or in a different context, or in any included contexts. Will even check "sister" context references. All the checks done on the time values in the dial plan, are done on the time values in the ifTime() and includes times: o the time range has to have two times separated by a dash; o the times have to be in range of 0 to 24 hours. o The weekdays have to match the internal list, if they are provided; o the day of the month, if provided, must be in range of 1 to 31; o the month name or names have to match those in the internal list. (0.5) If an expression is wrapped in $[ ... ], and the compiler will wrap it again, a warning is issued. (0.5) If an expression had operators (you know, +,-,,/,issued. Maybe someone forgot to wrap a variable name?* (0.12) check for duplicate context names. (0.12) check for abstract contexts that are not included by any context. (0.13) Issue a warning if a label is a numeric value. There are a subset of checks that have been removed until the proposed AAL (Asterisk Argument Language) is developed and incorporated into Asterisk. These checks will be: (if the application argument analyzer is working: the presence of the 'j' option is reported as error. if options are specified, that are not available in an application. if you specify too many arguments to an application. a required argument is not present in an application call. Switch-case using "known" variables that applications set, that does not cover all the possible values. (a "default" case will solve this problem. Each "unhandled" value is listed. a Switch construct is used, which is uses a known variable, and the application that would set that variable is not called in the same extension. This is a warning only... Calls to applications not in the "applist" database (installed in /var/lib/asterisk/applist" on most systems). In an assignment statement, if the assignment is to a function, the function name used is checked to see if it one of the currently known functions. A warning is issued if it is not. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 268 Differences with the original version of AEL 1. The $[...] expressions have been enhanced to include the ==, , and && operators. These operators are exactly equivalent to the =, , and & operators, respectively. Why? So the C, Java, C++ hackers feel at home here. 2. It is more free-form. The newline character means very little, and is pulled out of the white-space only for line numbers in error messages. 3. It generates more error messages - by this I mean that any difference between the input and the grammar are reported, by file, line number, and column. 4. It checks the contents of $[ ] expressions (or what will end up being $[ ] expressions!) for syntax errors. It also does matching paren/bracket counts. 5. It runs several semantic checks after the parsing is over, but before the compiling begins, see the list above. 6. It handles #include "filepath" directives. - ALMOST anywhere, in fact. You could easily include a file in a context, in an extension, or at the root level. Files can be included in files that are included in files, down to 50 levels of hierarchy... 7. Local Goto's inside Switch statements automatically have the extension of the location of the switch statement appended to them. 8. A pretty printer function is available within pbx_ael.so. 9. In the utils directory, two standalone programs are supplied for debugging AEL files. One is called "aelparse", and it reads in the /etc/asterisk/extensions.ael file, and shows the results of syntax and semantic checking on stdout, and also shows the results of compilation to stdout. The other is "aelparse1", which uses the original ael compiler to do the same work, reading in "/etc/asterisk/extensions.ael", using the original 'pbx_ael.so' instead. 10. AEL supports the "jump" statement, and the "pattern" statement in switch constructs. Hopefully these will be documented in the AEL README. 11. Added the "return" keyword, which will jump to the end of an extension/Macro. 12. Added the ifTime (time rangedays of weekdays of monthmonths ) else construct, which executes much like an if () statement, but the decision is based on the current time, and the time spec provided in the ifTime. See the example above. (Note: all the other time-dependent Applications can be used via ifTime) 13. Added the optional time spec to the contexts in the includes construct. See examples above. 14. You don't have to wrap a single "true" statement in curly braces, as in the original AEL. An "else" is attached to the closest if. As usual, be careful about nested if statements! When in doubt, use curlies! 15. Added the syntax regexten hint(channel) to precede an extension declaration. See examples above, under "Extension". The regexten keyword will cause the priorities in the extension to begin with 2 instead of 1. The hint keyword will cause its arguments to be inserted in the extension under the hint priority. They are both optional, of course, but the order is fixed at the moment- the regexten must come before the hint, if they are both present. 16. Empty case/default/pattern statements will "fall thru" as expected. (0.6) 17. A trailing label in an extension, will automatically have a NoOp() added, to make sure the label exists in the extension on Asterisk. (0.6) 18. (0.9) the semicolon is no longer required after a closing brace! (i.e. "];" === "}". You can have them there if you like, but they are not necessary. Someday they may be rejected as a syntax error, maybe. 19. (0.9) the // comments are not recognized and removed in the spots where expressions are gathered, nor in application call arguments. You may have to move a comment if you get errors in existing files. 20. (0.10) the random statement has been added. Syntax: random ( expr ) lucky-statement [ else unlucky-statement ]. The probability of the lucky-statement getting executed is expr, which should evaluate to an integer between 0 and 100. If the lucky-statement isn't so lucky this time around, then the unlucky-statement gets executed, if it is present. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 269 AEL Hints and Bugs The safest way to check for a null strings is to say $[ "${x}" = "" ] The old way would do as shell scripts often do, and append something on both sides, like this: $[ ${x}foo = foo ]. The trouble with the old way, is that, if x contains any spaces, then problems occur, usually syntax errors. It is better practice and safer wrap all such tests with double quotes! Also, there are now some functions that can be used in a variable reference, ISNULL(), and LEN(), that can be used to test for an empty string: ${ISNULL(${x})} or $[ ${LEN(${x})} = 0 ]. Assignment vs. Set(). Keep in mind that setting a variable to value can be done two different ways. If you choose say 'x=y;', keep in mind that AEL will wrap the right-hand-side with $[]. So, when compiled into extension language format, the end result will be 'Set(x=$[y])'. If you don't want this effect, then say "Set(x=y);" instead. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 270 The Full Power of AEL A newcomer to Asterisk will look at the above constructs and descriptions, and ask, "Where's the string manipulation functions?", "Where's all the cool operators that other languages have to offer?", etc. The answer is that the rich capabilities of Asterisk are made available through AEL, via: Applications: See Asterisk - documentation of application commands Functions: Functions were implemented inside ${ .. } variable references, and supply many useful capabilities. Expressions: An expression evaluation engine handles items wrapped inside $[...]. This includes some string manipulation facilities, arithmetic expressions, etc. Application Gateway Interface: Asterisk can fork external processes that communicate via pipe. AGI applications can be written in any language. Very powerful applications can be added this way. Variables: Channels of communication have variables associated with them, and asterisk provides some global variables. These can be manipulated and/or consulted by the above mechanisms. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 271 Asterisk Manager Interface (AMI) What is the Asterisk Manager Interface, or AMI? Read on... Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 272 The Asterisk Manager TCP IP API The manager is a client/server model over TCP. With the manager interface, you'll be able to control the PBX, originate calls, check mailbox status, monitor channels and queues as well as execute Asterisk commands. AMI is the standard management interface into your Asterisk server. You configure AMI in manager.conf. By default, AMI is available on TCP port 5038 if you enable it in manager.conf. AMI receive commands, called "actions". These generate a "response" from Asterisk. Asterisk will also send "Events" containing various information messages about changes within Asterisk. Some actions generate an initial response and data in the form list of events. This format is created to make sure that extensive reports do not block the manager interface fully. Management users are configured in the configuration file manager.conf and are given permissions for read and write, where write represents their ability to perform this class of "action", and read represents their ability to receive this class of "event". If you develop AMI applications, treat the headers in Actions, Events and Responses as local to that particular message. There is no cross-message standardization of headers. If you develop applications, please try to reuse existing manager headers and their interpretation. If you are unsure, discuss on the asterisk-dev mailing list. Manager subscribes to extension status reports from all channels, to be able to generate events when an extension or device changes state. The level of details in these events may depend on the channel and device configuration. Please check each channel configuration file for more information. (in sip.conf, check the section on subscriptions and call limits) Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 273 AMI Command Syntax Management communication consists of tags of the form "header: value", terminated with an empty newline (\r\n) in the style of SMTP, HTTP, and other headers. The first tag MUST be one of the following: Action: An action requested by the CLIENT to the Asterisk SERVER. Only one "Action" may be outstanding at any time. Response: A response to an action from the Asterisk SERVER to the CLIENT. Event: An event reported by the Asterisk SERVER to the CLIENT Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 274 AMI Manager Commands To see all of the available manager commands, use the "manager show commands" CLI command. You can get more information about a manager command with the "manager show command command" CLI command in Asterisk. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 275 AMI Examples Login - Log a user into the manager interface. Action: Login Username: testuser Secret: testsecret Originate - Originate a call from a channel to an extension. Action: Originate Channel: sip/12345 Exten: 1234 Context: default Originate - Originate a call from a channel to an extension without waiting for call to complete. Action: Originate Channel: sip/12345 Exten: 1234 Context: default Async: yes Redirect with ExtraChannel: Attempted goal: Have a 'robot' program Redirect both ends of an already-connected call to a meetme room using the ExtraChannel feature through the management interface. Action: Redirect Channel: DAHDI/1-1 ExtraChannel: SIP/3064-7e00 (varies) Exten: 680 Priority: 1 *Where 680 is an extension that sends you to a MeetMe room. There are a number of GUI tools that use the manager interface, please search the mailing list archives and the documentation page on the http://www.ast erisk.org web site for more information. Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 276 Ensuring all modules are loaded with AMI It is possible to connect to the manager interface before all Asterisk modules are loaded. To ensure that an application does not send AMI actions that might require a module that has not yet loaded, the application can listen for the FullyBooted manager event. It will be sent upon connection if all modules have been loaded, or as soon as loading is complete. The event: Event: FullyBooted Privilege: system,all Status: Fully Booted Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 277 Device Status Reports with AMI blank Content is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. 278 Some Standard AMI Headers Account: – Account Code (Status) AccountCode: – Account Code (cdr_manager) ACL: – Does ACL exist for object ? Action: – Request or notification of a particular action Address-IP: – IPaddress Address-Port: – IP port number Agent: – Agent name AMAflags: – AMA flag (cdr_manager, sippeers) AnswerTime: – Time of answer (cdr_manager) Append: – CDR userfield Append flag Application: – Application to use Async: – Whether or not to use fast setup AuthType: – Authentication type (for login or challenge) "md5" BillableSeconds: – Billable seconds for call (cdr_manager) CallerID: – Caller id (name and number in Originate & cdr_manager) CallerID: – CallerID number Number or "" or "unknown" (should change to "" in app_queue) CallerID1: – Channel 1 CallerID (Link event) CallerID2: – Channel 2 CallerID (Link event) CallerIDName: – CallerID name Name or "" or "unknown" (should change to "" in app_queue) Callgroup: – Call group for peer/user CallsTaken: – Queue status variable Cause: – Event change cause - "Expired" Cause: – Hangupcause (channel.c) CID-CallingPres: – Caller ID calling presentation Channel: – Channel specifier Channel: – Dialstring in Originate Channel: – Channel in Registry events (SIP, IAX2) Channel: – Technology (SIP/IAX2 etc) in Registry events ChannelType: – Tech: SIP, IAX2, DAHDI, MGCP etc Channel1: – Link channel 1 Channel2: – Link channel 2 ChanObjectType: – "peer", "user" Codecs: – Codec list CodecOrder: – Codec order, separated with comma "," Command: – Cli command to run Context: – Context Count: – Number of callers in queue Data: – Application data Default-addr-IP: – IP address to use before registration Default-Username: – Username part of URI to use before registration Destination: – Destination for call (Dialstring ) (dial, cdr_manager) DestinationContext: – Destination context (cdr_manager) DestinationChannel: – Destination channel (cdr_manager) DestUniqueID: – UniqueID of destination (dial event) Direction: – Audio to mute (read | write | both) Disposition: – Call disposition (CDR manager) Domain: – DNS domain Duration: – Duration of call (cdr_manager) Dynamic: – Device registration supported? Endtime: – End time stamp of call (cdr_manager) EventList: – Flag being "Start", "End", "Cancelled" or "ListObject" Events: – Eventmask filter ("on", "off", "system", "call", "log") Exten: – Extension (Redirect command) Extension: – Extension (Status) Family: – ASTdb key family File: – Filename (monitor) Format: – Format of sound file (monitor) From: