Chapter 11. The Asterisk GUI Framework

…I was constructing a lighthouse while all the others were making ships.

Charles Simic

This chapter introduces the components that comprise the GUI and help it work with Asterisk. It describes the installation of the web server and the GUI components for those who are not using the AsteriskNOW distribution. It also shows you how to modify the GUI to suit your purposes. Technical information is also provided so that developers wishing to create their own GUI or application can utilize the web server and GUI components. We’d like to thank the folks at Digium for writing this chapter, especially the code examples, which they developed and tested.

Why a GUI for Asterisk?

Since the beginning, Asterisk has been a phone system for the brave. In the early days it took guts and more than a bit of tenacity to make Asterisk do your bidding. Those willing to accept the learning curve, wade into the config files, and fight for their calls were rewarded with a powerful, flexible phone system (as well as a very marketable skill set). However, the mass market was not, and is not, ready to script extensions, manage peers, and handle the other tasks that are the crux of Asterisk administration.

Since the early pre-1.0 days, people have tried to tame the mighty Asterisk with config file generators tied to databases and managed via a range of graphical user interfaces (GUIs). The most successful of these did a fine job of creating an Asterisk-based application, but none of them provided the full flexibility that the raw scripting environment offers. By replacing the digital haiku of the dialplan with a limited list of options, the resulting system is reduced from Asterisk to an Asterisk-based system. Not a bad thing, but not the whole enchilada.[129]

In order for a GUI to be the Asterisk GUI, it would have to leave intact the manually scripted configuration files that have been the lingua franca of Asterisk since the dawn of time. It would have to provide a simple, graphical means of configuration without compromising the underlying Asterisk software or irrevocably fixing decisions that should be left open to the end user. It would also have to provide advanced functionality without taxing the computer or stealing valuable resources from the core goal of processing calls.

Coinciding with the release of Asterisk 1.4, Digium launched the Asterisk GUI project. The GUI was originally conceived as a component of Digium’s Asterisk embedded appliance. The appliance, sold as the Asterisk Appliance Developers Kit (AADK) as well as in a standalone configuration, is a small, solid-state Linux computer with optional analog (and potentially digital) interfaces. The GUI was built using a flexible and expandable framework that placed as much of the display and validation logic as possible on the client computer. It also took into consideration the need to preserve handwritten config files while providing an automated means of editing them. The resulting framework is known as AJAM (a play on the popular “Web 2.0” technology known as Ajax), which means Asynchronous JavaScript and Asterisk Manager. The core AJAM code, a series of AJAM-enabled web pages, and an extension to the Asterisk manager work together to form the Asterisk GUI framework.

What Is the GUI?

The Asterisk GUI is the interface that comes with the AsteriskNOW distribution or can be added to an existing Asterisk installation. The default interface is geared toward the user who wants to use Asterisk as a PBX for a small business with fairly typical telecom needs. It can best be thought of as a sample of what can be done using AJAM; think of it as a beta interface that can be expected to evolve according to the desires of the community. This has caused a lot of excitement in the Asterisk community, because the underlying technologies behind the GUI raise the bar on what a PBX interface can become. It also enables you to build your own interfaces that are tuned to your unique requirements.

Mark Spencer Talks About the GUI

Asterisk is a powerful telephony platform. However, that power is only as valuable as its ability to be used by a particular target user. There is a lot of value to having graphical interfaces (GUIs) for Asterisk. Most GUIs are specifically designed to support a particular task. For example, some GUIs are designed specifically for voicemail systems. Others are specifically targeted to the hospitality industry. There is some demand to have a GUI that targets Asterisk generally, but there is a natural trade-off between the ease of use and simplicity of a GUI, versus the number of available features. For example, the GUI that a seasoned systems administrator might require would likely be different than that of an office administrator who is only responsible for simple moves, adds, and changes to the system. Given this wide ranging demand, Digium developed a GUI framework called (uncreatively) the Asterisk GUI. Rather than developing a single GUI, Digium developed different GUIs and a framework to trivialize the creation and modification of GUIs for different segments.

A second goal was to make sure that the GUI interacted with Asterisk’s traditional configuration methods in a way that did not preclude someone from using them. Most GUIs for Asterisk use an intermediate configuration format or database, then spit out configs for Asterisk to use. Unfortunately that means that any option that is not presented within the GUI cannot be “manually” set in the configuration files. By contrast, the Asterisk GUI actually modifies your traditional Asterisk configuration files, meaning that your changes in the GUI and your changes to the files themselves can co-exist and even flow back and forth. As an example, if you change the caller ID for a user in users.conf then refresh the GUI, you’ll see the change in the GUI as well. Likewise if you change it in the GUI and reload the file, you’ll see the change in the file. If you add new settings that are not presented in the GUI (for example if you add nat=yes to a particular entry in users.conf, then change the caller ID in the GUI, you’ll see that the nat=yes line will remain in the file even though the caller ID change goes through. Comments are also generally preserved across GUI edits. This means that not only is the GUI no longer required to display all possible configurations, since esoteric ones can be set manually. This also means that when someone starts by using the Asterisk GUI and then outgrows it, there is a natural path for them to be able to start creating more sophisticated functions without abandoning the GUI with which they’re familiar.

Using the GUI

When you first log in to a newly created GUI, the system walks you through a wizard that lets you set up the basic elements of your phone system.

Caution

The GUI may not be able to detect all types of TDM interfaces, and thus may report that it cannot find any cards even though you have some installed. It is expected that the GUI will eventually be able to detect and manage any cards that use the Zaptel interface, but this functionality is going to be complex, and is still in development at this time.

The wizard walks you through some basic settings such as extension length and dialing rules. We are not going to get into detail on how the default GUI works. It is in constant development, and what we write about here is not likely to be what you will experience when you read this.

GUI elements

The standard GUI that comes with AsteriskNOW (or can be downloaded via SVN) has a standard set of elements that represent the sorts of things a typical small office PBX might want. The menu items are currently:

  • Users

  • Conferencing

  • Voicemail

  • Call Queues

  • Service Providers

  • Calling Rules

  • Incoming Calls

  • Voice Menus

  • Record a Menu

  • Active Channels

  • Graphs

  • System Info

  • Backup

  • Options

Architecture of the Asterisk GUI

Before we get too far into exploring the Asterisk GUI (or developing your own), it’s important to understand the flow of information between the client (the web browser) and Asterisk. Since these interfaces are Ajax applications, there are a lot of pieces that aren’t immediately obvious. The flow of control goes something like this:

  • The browser “surfs to” the URL for your management application.

  • Asterisk’s web server sends the browser an HTML page, libraries, and the application itself (which is written in JavaScript and makes heavy use of Ajax).

  • The user interacts with the browser; as needed, the JavaScript application sends commands back to the web server. These commands are in the form of URLs that request some action from the Asterisk server itself.

  • The web server interprets the URLs. If the user has logged in successfully, it sends a command (an action) to Asterisk via the Asterisk Manager Interface (AMI), described in Chapter 10.

  • Asterisk executes the action and the results (a status code and possibly data) to the web server.

  • The web server sends Asterisk’s response back to the JavaScript application on the browser.

  • The JavaScript application updates the browser’s display.

While it may sound a little complicated at first glance, don’t be intimidated. It’s a very flexible and powerful architecture that can be used for a myriad of applications, not just an Asterisk GUI. For now, however, we’ll concentrate on enhancing the Asterisk GUI. Let’s begin by configuring the underlying pieces, and then move on to installing and modifying the Asterisk GUI.

Components of the Asterisk GUI

Let’s take a closer look at some of the key components of the Asterisk GUI. We’ll use these components later in the chapter to modify the Asterisk GUI.

Asterisk Manager Interface

As explained in Chapter 10, the Asterisk Manager Interface allows external programs to control Asterisk. The Manager interface is the heart of the Asterisk GUI, as it does all of the heavy lifting.

Manager over HTTP and the Asterisk web server

The web server built into Asterisk allows manager commands to be sent to Asterisk via HTTP, instead of creating a socket connection directly to the Manager interface. This makes it much simpler for a web application to issue AMI commands to Asterisk using the Asynchronous JavaScript Asterisk Manager (AJAM), which we will cover shortly. The web server can also be configured to serve static content, such as HTML files and images.[130]

AJAM and JavaScript

The AJAM framework uses JavaScript and XML to asynchronously send commands to Asterisk, and to update the information displayed in the web browser.

Installing the Asterisk GUI

If you didn’t install AsteriskNOW, you need to download and install the Asterisk GUI files. Once the files are downloaded, you simply compile and install them as part of your Asterisk installation.

Note

You need Asterisk 1.4 or later in order use the Asterisk GUI.

You can get the latest version of the GUI files by checking them out of Digium’s Subversion repository.[131] If you have Subversion installed on your computer, you can downloaded the GUI code by using the following command:

# cd /usr/src   # or wherever you prefer to download source code to
#svn co http://svn.digium.com/svn/asterisk-gui/trunk asterisk-gui

Installing the GUI is simple as this:

# cd asterisk-gui
# ./configure
# make
# make install
#make samples

After running the previous commands, the GUI files are installed and part of your Asterisk distribution.

Setting up http.conf and manager.conf

Configuring the Asterisk web server to process AJAM requests involves several simple steps. In the /etc/asterisk/http.conf file, add (or un-comment) the following:

[general]
enabled=yes
enablestatic=yes      ; without this, you can only send AMI commands, not display 
                      ; html content

bindaddr=0.0.0.0          ; address you want the Asterisk HTTP server to respond on
bindport=8088             ; port you want the Asterisk HTTP server to respond on
prefix=asterisk           ; will form part of the URI, similar to a directory name

Now that we’ve got httpd.conf set up, we can serve up content to a browser. To allow the web client to send commands to Asterisk, we have to make some changes to the Asterisk Manger Interface (AMI). We do this by adding a few lines to the [general] section of manager.conf, and by adding a user account with the config permission set. Open up manager.conf and edit it to match the following:

[general]
enabled=yes      ; you may already have AMI enabled if you are using it for other things
webenabled=yes   ; this enables the interaction between the Asterisk web server and AMI

[asterisk_http] ; you can name the user whatever you want
secret = gooey
read = system,call,log,verbose,command,agent,user,config
write = system,call,log,verbose,command,agent,user,config

Save the changes and restart Asterisk. You should be able to connect to Asterisk’s web server through the following URI:

http://localhost:8088/asterisk/static/ajamdemo.html

If for some reason you’re having problems getting to that demo page, go back to the asterisk-gui source code directory and run:

# make checkconfig

And that’s it! Asterisk is now web-enabled. Now, let’s move on to the actual work of developing with the Asterisk GUI.

Developing for the Asterisk GUI

Once you’ve installed the files for the Asterisk GUI, you can begin to play with developing for the GUI. Over the next few sections, we’ll walk through setting up the various components and putting them together to enhance and expand the capabilities of the GUI.

Issuing Manager Commands over HTTP

The Asterisk GUI issues commands to Asterisk by calling specially crafted URLs to the Asterisk web server. This section provides examples of some commonly used commands (actions) and the corresponding web server responses. These AMI URLs have the following general structure:

http://hostname:8088/asterisk/rawman?action=command&....parameter=value pairs...
http://hostname:8088/asterisk/manager?action=command&....parameter=value pairs...
http://hostname:8088/asterisk/mxml?action=command&....parameter=value pairs...

The difference between the rawman, manager and mxml URLs is important. The web server exports three different views of the AMI interface. If you use a rawman URL, the server returns a series of keyword/value pairs in the HTTP response. If you use a manager URL, the server returns the result formatted as HTML. In a similar style, if you use a mxml URL, the server returns the results formatted in XML. For modern Ajax-style applications, the rawman and mxml forms are probably more useful.[132]

The actions that can be sent to the server, along with their parameters, are the ordinary manager commands described in Appendix F. Note that the LOGIN and CHALLENGE actions are unique in that they aren’t sent to Asterisk itself, but are processed by the Manager interface to authenticate the user. If the user hasn’t authenticated correctly, the server returns an error response rather than sending the action to Asterisk for processing.

Let’s look at some commonly used actions, and see how we can use them to control the server.

LOGIN

The LOGIN command authenticates credentials for the Manager interface’s HTML view. Once you are logged in, Asterisk stores a cookie on your browser (valid for the length of the httptimeout setting). This cookie is used to connect to the same session. The URL:

http://localhost:8088/asterisk/rawman?action=login&username=asterisk_http&secret=gooey

sends a login command to the web server that includes the credentials. If successful, the web server responds with:

Response: Success
Message:  Authentication accepted

This, of course, is a very simplistic way for a login to work. Sending the username and secret password in a URL is bad practice, though it’s very useful during development. A more appropriate way to handle the login, and an example of more complex command processing, is to use a challenge/response sequence. Issue a request like this:

http://localhost:8088/asterisk/rawman?action=challenge&AuthType=md5

The CHALLENGE command initiates a challenge/response sequence that can be used to log in a user. The server responds by sending a challenge (an arbitrary string) in the response:

Response: Success
Challenge: 113543555

Your application answers the challenge by computing the MD5 hash of the challenge concatenated with the user’s password. Here’s how a user might manually calculate the MD5 hash:

# echo -n 113543555gooey | md5sum50a0f43ad4c9d99a39f1061cf7301d9a  -

You can then use the calculated hash as the login key in a URL like this:

http://localhost:8088/asterisk/rawman?action=login&username=asterisk_http&authtype=md5&key=50a0f43ad4c9d99a39f1061cf7301d9a

Warning

For security reasons, the login action must take place within five seconds of the challenge action. Note also that cookies must be enabled for the challenge/response to work, as the cookie ensures that the login action uses the same manager session ID as the challenge action.

If you use a manager URL to request the challenge (instead of using rawman), the response will be formatted as HTML:

<title>Asterisk&trade; Manager Interface</title>
<body bgcolor="#ffffff">
<table align=center bgcolor="#f1f1f1" width="500">
<tr><td colspan="2" bgcolor="#f1f1ff"><h1>&nbsp;&nbsp;Manager Tester</h1></td></tr>
<tr><td>Response</td><td>Success</td></tr>
<tr><td>Challenge</td><td>113543555</td></tr>
</table>
</body>

Similarly, if you use the mxml view instead, you will receive a response formatted as XML:

<Ajax-response>
   <response type='object' id='unknown'>
      <generic response='Success' challenge='113543555' />
   </response>
</Ajax-response>

Other than the formatting, there are no other differences between the three types of responses. For most applications, digging the challenge out of the keyword/value pairs will be much simpler than using rawman or mxml in a situation like this, where you don’t need to display the HTML to the user.

Transferring a call

The REDIRECT action can be used to transfer a call. Simply generate a URL such as:

http://localhost:8088/asterisk/rawman?action=redirect&channel=SIP/John-ae201e78&priority=1&exten=6001

This URL transfers the specified channel to another extension and priority in the dialplan. The response to this action is:

Response: Success
Message: Redirect Successful

Reading a configuration file

The GETCONFIG command returns the contents of a configuration file, or portion thereof. The URL:

http://localhost:8088/asterisk/rawman?action=getconfig&filename=users.conf

returns the contents of the users.conf file. The Asterisk GUI uses this functionality to present the current Asterisk configuration to the end user. The response looks like this:

Response: Success
   Category-000000: general
   Line-000000-000000: fullname=New User
   Line-000000-000001: userbase=6000
   Line-000000-000002: hasvoicemail=yes
   Line-000000-000003: hassip=yes
   Line-000000-000004: hasiax=yes
   Line-000000-000005: hasmanager=no
   Line-000000-000006: callwaiting=yes
   Line-000000-000007: threewaycalling=yes
   Line-000000-000008: callwaitingcallerid=yes
   Line-000000-000009: transfer=yes
   Line-000000-000010: canpark=yes
   Line-000000-000011: cancallforward=yes
   Line-000000-000012: callreturn=yes
   Line-000000-000013: callgroup=1
   Line-000000-000014: pickupgroup=1
   Line-000000-000015: host=dynamic
   Category-000001: 6007
   Line-000001-000000: fullname=Bill Savage
   Line-000001-000001: secret=1234
   Line-000001-000002: email=bsavage@digium.com
   Line-000001-000003: cid_number=6001
   Line-000001-000004: zapchan=
   Line-000001-000005: context=numberplan-custom-1
   Line-000001-000006: hasvoicemail=yes
   Line-000001-000007: hasdirectory=no
   Line-000001-000008: hassip=yes
   Line-000001-000009: hasiax=yes
   Line-000001-000010: hasmanager=no
   Line-000001-000011: callwaiting=yes
   Line-000001-000012: threewaycalling=yes
   Line-000001-000013: mailbox=6007
   Line-000001-000014: hasagent=yes
   Line-000001-000015: group=

Updating configuration files using UPDATECONFIG

The UPDATECONFIG action is used to update one or more settings in a configuration file. For example, to delete a user you should use a URL like this:

http://localhost:8088/asterisk/rawman?action=updateconfig&reload=yes&srcfilename=users.conf&dstfilename=users.conf&Action-000000=delcat&Cat-000000=6003&Var-000000=&Value-000000=

Error response

A user must be logged in to the web server before any other commands can be issued. Any of the commands we’ve discussed will return an error response if the user is not authenticated. If it’s not given by an authenticated user, this URI http://localhost:8088/asterisk/rawman?action=ping returns this response to indicate an error:

Response: Error
Message:  Authentication Required

Ajax, AJAM, and Asterisk

As an acronym, Ajax stands for Asynchronous JavaScript and XML. While the term includes the words asynchronous and XML, this does not mean that you can make only asynchronous requests, nor are you required to use XML. Some authors describe Ajax as simply a combination of HTML, JavaScript, DHTML, and DOM. The next generation browsers, such as Mozilla/Firefox, use an XMLHttpRequest (a JavaScript object) to send an asynchronous request to the server. The request is made in the background and processed by the server.

Back on the browser, the result is handled by a callback: whatever the server returns can be stored and used to update the page being displayed. For Internet Explorer 5 or later, the XMLHttp ActiveX object serves the same purpose.

Form processing in a traditional web application

HTML forms are usually submitted by using a submit button (type=submit). When the user clicks the submit button, processing stops, and doesn’t continue until the server returns a new page:

<FORM action="login.php" method="POST">
  <input type=text name="username">
  <input type=password name="password">
  <input type=submit> 
</FORM>

Before going any further with Ajax or JavaScript, let’s take a look at how a traditional web application works. Traditional web applications use HTML’s <FORM> element to define a form in which all of the parameters a user needs to send to the server are defined. In addition the action="login.php" informs the browser where to send all of these variables. The method="POST" tells the browser how to send these variables to the server.

Form processing in an Ajax application

An Ajax application uses JavaScript to send the contents of a form to the server. If you have made the request asynchronously, your JavaScript code doesn’t wait for the server to respond. This also means that you can let the users continue to interact with the page, even though a request may be taking place in the background. This can be dangerous and, thus, you may want to restrict certain actions until a request has completed. The browser, by default, gives no visual indication that a request is being made in the background. It is your responsibility to inform the user of the progress of a request. Here’s the code for submitting the contents of the username and password fields via Ajax:

<script language="javascript" type="text/javascript">
 function submitform(){
  var uname = document.getElementById("username").value;
  var pwd = document.getElementById("password").value;
  // xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); // IE 7
  // xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); // IE 5
  xmlHttp = new XMLHttpRequest(); // Mozilla or Firefox
  
  var url = "/rawman?action=login&username=" + escape(uname) + "&secret=" + escape(pwd);
  
  xmlHttp.open("GET", url, true);
  xmlHttp.onreadystatechange = dosomething; 
  // dosomething() would be another JavaScript function
  xmlHttp.send(null);
}
</script>

The getElementById() method reads the value of the username and the password fields. This code then gets an XMLHttpRequest object, which it uses to send these values back to the server. Note that the kind of object you need depends on whether your users are using Internet Explorer 7, 5, or Mozilla/Firefox. It’s fairly easy to write code to handle all of these situations, or to use a library like Prototype to handle platform independence for you. The username and password are encoded in a URL and sent to the server. The call to xmlHttp.onreadystatechange registers a handler to process the result that the server returns to us.

This code only deals with making the XMLHttp request, and it tells the browser to call the dosomething() function when there is a response from the server. Here’s a dosomething() function that handles this response:

<script language="javascript" type="text/javascript">
  function dosomething() {
    if (xmlHttp.readyState == 4) {
      var login_response = xmlHttp.responseText;
    }
  }
</script>

Tip

Make sure that each XMLHttp step has completed (with either success or failure) before performing the next one.

This function is called whenever there’s a change in the state of the HTTP request. The if statement saves the response only if the request’s readyState is 4, which means that the request has completed. The JavaScript variable login_response now contains the response of the login page.

Note that this is very far from being production-ready code. In particular, the simplistic username and password handling is appropriate for testing, but would be a serious security problem in a production system—even if the application is used only on a private network. To build more robust and secure password handling, use the challenge/response system presented earlier. If you want to learn more about writing Ajax web applications, we recommend Head Rush Ajax by Brett McLaughlin (O’Reilly).

The Prototype framework

Prototype (http://prototypejs.org) is a JavaScript framework released under an MIT-style license. Prototype can make your job extremely easy while developing an Ajax application. It provides many ways to make your code shorter and clearer. For example, in the submitform function, the call to document.getElementById() can be replaced by the $() function. Likewise, the call to value to get the DOM element’s content can be replaced with a call to $F(). Thus, document.getElementById("username").value becomes simply $F('username'); the result is code that’s much simpler and more readable.

Prototype also makes it easy to make XMLHttp requests in an elegant manner. Using Prototype’s Ajax object, the submitform() function can be rewritten as:

<script language="javascript" type="text/javascript">
function submitform(){
   var url = '/rawman';
   var pars = 'username=' + escape($F('username')) + '&secret=' + escape($F('password'));
   
var myAjax = new Ajax.Request( url, 
  { method: 'get', 
    parameters: pars, 
    onComplete: dosomething
  });

}
</script>

Not only is this code much shorter, you don’t have to write browser-specific code in your web pages; Prototype takes care of the differences between Mozilla/Firefox and the various versions of Internet Explorer. Furthermore, it takes care of testing the request’s readyState, so you leave that annoying if statement out of your handler. Prototype has lots of built-in functions, some of which have been extensively used in the Asterisk framework. There’s no room to discuss them here, but for more information, see the Short Cuts Prototype Quick Reference by Scott Raymond and Prototype and Scriptaculous: Taking the Pain Out of JavaScript by Chris Angus, both from O’Reilly.

Customization of the GUI

Now that we’ve explored the different pieces that form the foundation of the Asterisk GUI, we have what we need to be able to explore the GUI itself and modify it to fit our needs. To get to the Asterisk GUI, go to the following address in your browser: http://localhost:8088/asterisk/static/config/cfgbasic.html.

Looking at Figure 11-1 might lead you to conclude that the Asterisk GUI is simply one more Asterisk GUI in an already crowded space. Nothing could be further from the truth. This GUI doesn’t just allow you to tweak it, it practically begs you to. In this section we are going to discuss how you can modify the GUI and use AJAM to build your own extensions to the GUI. In order to benefit the most from this information, you need some HTML and JavaScript knowledge.

A screenshot of the Asterisk GUI
Figure 11-1. A screenshot of the Asterisk GUI

The GUI home page is named cfgbasic.html. All other pages are loaded into the iframe contained within the cfgbasic.html page. By default, cfgbasic.html loads home.html into the main frame.

For most changes to the GUI, you’ll eventually need to modify cfgbasic.html, which is the login screen.

Adding a new tab to the GUI

As an example of customizing the Asterisk GUI, let’s create a new tab that displays the contents of extensions.conf. First, we need to create a file and put it in the /var/lib/asterisk/static-html/config directory. In this example, we’ll name the file test.html:

<script src="scripts/prototype.js"></script>
<script src="scripts/astman.js"></script>
<script>
function localAjaxinit() {
       parent.loadscreen(this);
       makerequest('g','extensions.conf', '' , function(t){
               $('ExtensionsDotConf').innerHTML = "<PRE>" + t + "</PRE>";
       });
}
</script>
<body onload="localAjaxinit()" bgcolor="EFEFEF">
       <div id="ExtensionsDotConf"></div>
</body>

This code simply displays the configuration of the extensions.conf file. Obviously it’s a very simple example, but it shows the fundamentals of creating a new page for the Asterisk GUI. Let’s walk through the example step by step.

The first line tells the browser to load the Prototype library. The second line tells the browser to load the astman.js file, which contains much of the code designed to interact with the Manager interface.

Next, we define a function called localAjaxinit. The localAjaxinit function first tells this page’s parent (cfgbasic.html in this case) to run the loadscreen function, passing in this page as the parameter. This causes the main GUI screen to load our new test.html inside the iframe. The second thing we do inside the localAjaxinit function is to use the makerequest function. The makerequest function is defined in astman.js and makes it very convenient to make requests to the web server.[133]

The first parameter of the makerequest function specifies what type of request is being made. It can be set to any of the following:

'g'

Use the GetConfig action to retrieve the configuration from the configuration file specified in the second parameter.

'u'

Use the UpdateConfig action to update the configuration in the configuration file specified in the second parameter. The third parameter to the function specifies the configuration data that should be updated.

''

If the first parameter to the makerequest function is a set of single quotes, then the custom action specified in the third parameter will be sent.

The fourth parameter is the callback function that will be called with the response to the Ajax request.

The rest of our test.html simply contains an HTML body with a div element, which is where we’ll place the configuration data when we get it. Note that the HTML body tag has an onload attribute, which causes the browser to execute the localAjaxinit function once the page has finished loading.

Now that we’ve created a new page, we need to edit cfgbasic.html to add this page as a panel in the GUI. Open cfgbasic.html and search for a JavaScript function named returnpanels and insert this code in the list of panels, where you would like your panel to appear:

newpanel( ["Test", "test.html", "Test"]);

Now reload the GUI in your browser. You should see a new tab on the lefthand side named Test that displays the configuration values for extensions.conf when clicked.

While there’s a lot more to learn about the AJAM interface and the Asterisk GUI, this example should show just how easy it is to add new functionality to the GUI. In this next example, we’ll show how simple it is to expose a setting from the configuration files in the GUI.

Exposing configuration settings in the GUI

As explained earlier, one of the unique benefits of the Asterisk GUI over the other graphical frontends to Asterisk is that it updates the configuration files in place, taking special care not to overwrite or erase any extra settings you might have in your configuration files. To show just how easy it is to expose new settings in the GUI, we’ll add a simple checkbox to the GUI to make it possible to set the nat setting in users.conf.

If you open the GUI and click on the tab labeled Users, the GUI loads the file named users.html in the iframe. Let’s open up users.html (usually located in /var/lib/asterisk/static-http/config) and begin modifying it to add our checkbox.

First, search near the top of the file where a variable named fieldnames is defined. This variable contains a list of all of the field names that will be set by this page of the GUI. Simply add nat to the end of the list, or add the following line directly below the current definition for fieldnames.

fieldnames.push('nat');

This tells the Asterisk GUI that we want to be able to see the value of nat and to be able to set it as well. In order to see or set the value, however, we need to add an element to the HTML form. To do that, search users.html for the IAX checkbox, and add the following lines between it and the CTI checkbox.

 <tr>
   <td align=right><input type='checkbox' id='nat'></td>
   <td>NAT</td>
</tr>

Simply reload the page, and that’s all there is to it. With just a few lines of additional code, we’re able to expose the nat setting to the GUI. It couldn’t be much simpler!

Note

As you’re developing for the Asterisk GUI, you’ll probably find that debugging Ajax and JavaScript code can be somewhat difficult at times. We strongly suggest you make use of an extension to Mozilla Firefox named Firebug that greatly simplifies the task of debugging Ajax, JavaScript, and HTML. Check it out at http://www.getfirebug.com. There is also a scaled-down version for Internet Explorer known as Firebug Lite, which is available for download at the same web site.

For More Information

Over the course of this chapter, we’ve introduced you to the Asterisk GUI and the AJAM framework. We’ve covered the architecture of how the GUI works, and how to modify the GUI. If you would like more information on developing a graphical interface for Asterisk, please refer to the GUI Developers Guide located at http://asterisknow.org/developers/gui-guide.



[129] In fact, two of the authors of this book once attempted to write the ultimate Asterisk GUI. Lucky for you, they abandoned the project and began writing Asterisk documentation instead!

[130] You may be asking yourself, “Why embed a web server inside of Asterisk? Why not just use an external web server?” While you can use an external web server to serve up the Asterisk GUI, it’s beyond the scope of this chapter, as the security model behind Ajax permits Ajax requests only to the same domain, port, and protocol that sent the HTML page. This is often referred to as the same-origin policy.

[131] There is currently no way to download the GUI via FTP. That situation may change at any time, so feel free to check the Asterisk web site for updated information.

[132] By similar reasoning, the manager form is much easier for humans to use for debugging purposes.

[133] In reality, makerequest is a simple wrapper around a call to Prototype’s Ajax.Request method.

Get Asterisk: The Future of Telephony, 2nd Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.