Parsing Asterisk Configuration

If you are writing integrations for Asterisk PBX, you may feel the need to create an internal telephone directory.

Today I’ve been putting together Phonebook, a web-based phonebook which pulls data from an asterisk server. I used JQTouch for the interface, with PHP to process data files. The system also use a CSV file exported from our hosted gmail to ensure that people’s names are displayed consistently between the email and phone directory.

‘Phonebook’ web app

The configuration

Asterisk’s configuration files are INI-like, and you’ll find them in /etc/asterisk/ on most systems.

Just one important thing though, asterisk lets you use brackets ( ) in caller-IDs or other fields, which will cause PHP’s parse_ini_file() function fail, since that is a syntax error in the format it is expecting.

To save yourself some trouble, this is a class which I wrote, which will load INI data into an associative array:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class ns_ini_parser {
    /* Mike's non-standard INI parser for asterisk files. https://mike42.me
        Note that PHP's parse_ini_file will die with a syntax error on key = value (bracket), which makes it unsuitable. */

    function parse_string($string) {
        $lines        = explode("n", $string);
        $section    = "0";
        $result        = array();
        foreach($lines as $line) {
            $line = trim($line);
            if($line == "" || substr($line, 0,1) == ";") {
                /* Comment, no action */
            } elseif(substr($line, 0,1) == "[") {  /* [section] */
                $l          = strlen($line);
                $line          = trim(substr($line, 1, $l - 2));    /* Strip brackets */
                $section      = $line;
                if(!isset($result[$section])) {
                    $result[$section] = array();
                }
            } else {                /* key = val */
                $parts = explode("=", $line);
                $key = trim($parts[0]);    /* The key is everything left of the equal */
                unset($parts[0]);    /* Got that, unset it */
                $val = trim(join("=", $parts));    /* Value is everything on the righht */
                $result[$section][$key] = $val;
            }
        }
        return $result;
    }

    function parse_file($path) {
        $string = file_get_contents($path);
        return $this -> parse_string($string);
    }
}

The example usage below will list user’s extensions next to their caller ID, which you could use as the basis for a web phonebook:

1
2
3
4
5
6
7
8
9
/* Example PHP code to parse asterisk configuration */
$config_parser = new ns_ini_parser;
$users  = $config_parser -> parse_file("/etc/asterisk/users.conf");

foreach($users as $id => $user) {
    if(is_numeric($id)) { /* Only show numbers, not other sections */
        echo "<a href="tel:$id">$id</a> ".$user['fullname']."<br />";
    }
}

I don’t think it gets easier than that! I’ll post the rest once you can manage the contacts as well.