You are hereAsterisk and Polycom Phone Script Tips

Asterisk and Polycom Phone Script Tips


By steve - Posted on 28 August 2006

I've been using Asterisk and Polycom phones since the Spring of 2005 and, other than running into a few glitches, have really liked working with both. I've developed some scripting shortcuts that really save time in deployment and configuration changes. The setup described has been tested with Polycom 50x phones and several asterisk builds.

My basic asterisk setup is pretty standard. I put all of the asterisk configuration files in /etc/asterisk. I've split sip.conf into the primary sip.conf and then do an include to my sip-extensions.conf file where I keep all my extension specific settings.

Note: When you see mac or mymac, you would mentally want to substitute the 12 character hex value associated with your phone(s). So a reference to mac.cfg really means 0005f201d155.cfg.

sip.conf:

[general]
context=internal
bindport=5060
bindaddr=0.0.0.0
dtmfmode=rfc2833
progressinband=no

#include sip-extensions.conf

sip-extensions.conf:

[1001]
mymac=0005f201d155
username=1001
secret=9999
mailbox=1001
callerid=1001 User Name Here
context=internal
type=friend
host=dynamic
allow=all
callgroup=1
pickupgroup=1
canreinvite=no

...

The section is setup to match for each extension. So if the extension is 1001, then use that for the username, mailbox, and caller ID settings. "User Name Here" gets replaced with the name as you want to see it on the display. I may adjust callgroup and pickupgroup as needed, but these work in small offices.

I have a non-asterisk entry in the extensions configuration:
mymac=xxxxxxxxxxxxx

This is where I put the mac address of the phone associated with that extension. Asterisk doesn't care that I have an odd entry there; it just ignores it. However, by putting the mac address associated with the asterisk extension, I can then write scripts that can do phone-specific things and extension-specific things.

SCRIPT FOR BUILDING PHONE CONFIGURATIONS

I've written a perl script called makephones to read the sip-extensions.conf file, process entries in the phone1.cfg Polycom xml file, and generate an individual phone setup. The setup includes the phone specific xml configuration file, a directory, and a setup xml file. These files are accessed via ftp when the phones boot up. My DHCP server provides a bootp entry which the phones use to attempt ftp access (using a specified user/password in the phone's configuration) to get settings and save log files. There is plenty of information about how to do this in the polycom documentation and at www.voip-info.org.

To customize your phone setup, make changes to phone1.cfg. This is the template that is used to generate all the other files. phone1.cfg is not used directly by the phones, but sip.cfg is.

By reading in the sip-extensions entries (with mymac address), I can generate a fresh configuration file for each phone. If I don't want an extension to get one, I either don't specify the mymac entry or set it to blank (mymac=).

You can generate all phones this way:
makephones all

Or just one extension:
makephones 1001

Note: if you want to make changes to defaults for a specific extension, you can save them in the mac-phone.cfg file where overrides can be saved for just that phone. For instance, if you have blocked the "Missed Calls" function because it is useless to the phones that ring when an operator call comes in (say you are ringing 4 extensions when somebody presses 0 for the operator), but you want to have it available to other users, you can put that setting in each phone's mac-phone.cfg file:

<?xml version="1.0" standalone="yes"?>
<PHONE_CONFIG>
        <OVERRIDES
        call.serverMissedCall.1.enabled="0"
        />
<PHONE_CONFIG>

makephones:

#!/usr/bin/perl
# This program takes entries from your sip-extensions.conf file and
# creates needed .cfg files in your current directory,
# using your latest phone1.cfg file.
# These files include:
#       mac.cfg                 polycom phone configuration pointer file
#                               (where mac is the mac layer ethernet
#                               address of the phone)
#                               Note: replaced each time this runs
#       mac-setup.cfg           polycom phone setup configuration file
#                               based on phone1.cfg
#                               Note: replaced each time this runs
#

$asterisk_dir =     '/etc/asterisk';
$sip_conf =         $asterisk_dir . '/sip-extensions.conf';
$polycom_dir =      '/home/PlcmSpIp';
$polycom_template = $polycom_dir . '/phone1.cfg';
$polycom_directory = $polycom_dir . '/000000000000-directory.xml';

$myexten = $ARGV[0];

@mods    = ();
@xmlfile = ();

# User must enter: makephones all
# or               makephones extension
if ($myexten eq '') {
        die "Command format:\n\nmakephones all\|extension\n\n";
}

# These are the variables we're going to change

@mod_vars = qw(
  reg.1.displayName
  reg.1.address
  reg.1.label
  reg.1.type
  reg.1.auth.userId
  reg.1.auth.password
  msg.mwi.1.subscribe
  msg.mwi.1.callBack
);

# This maps the fields from sip.conf to the above:

%map_sip = (
    "callerid" => "reg.1.displayName",
    "secret"   => "reg.1.auth.password"
);


# First, we create a hash of arrays.  Each array has the info for the
# individual extension

my %phones;
my @sipinfo = ();
open( SIPINFO, "< $sip_conf" );
@sipinfo = <SIPINFO>;
foreach $sip_line (@sipinfo) {
  if (substr($sip_line,0,1) ne ';') {
    if ( $sip_line =~ m{\[(.*?)\]\s+$}i ) {
        $extension = $1;
        push ( @{ $phone{$extension} },
            "msg.mwi.1.subscribe=" . '"' . $extension . '"' );
        push ( @{ $phone{$extension} },
            "msg.mwi.1.callBack=" . '"' . $extension . '"' );
        push ( @{ $phone{$extension} },
            "reg.1.address=" . '"' . $extension . '"' );
        push ( @{ $phone{$extension} },
            "reg.1.label=" . '"' . $extension . '"' );
        push ( @{ $phone{$extension} },
            "reg.1.auth.userId=" . '"' . $extension . '"' );
        push ( @{ $phone{$extension} },
            "reg.1.type=" . '"' . "private" . '"' );
    }
    else {
        if ( $sip_line =~ m{callerid=(.*?)\s+$}i ) {
            push ( @{ $phone{$extension} },
                $map_sip{"callerid"} . '="' . $1 . '"' );
        }
        if ( $sip_line =~ m{secret=(.*?)\s+$}i ) {
            push ( @{ $phone{$extension} },
                $map_sip{"secret"} . '="' . $1 . '"' );
        }
        if ( $sip_line =~ m{mymac=(.*?)\s+$}i ) {
            push ( @{ $phone{$extension} },
                "mymac=" . $1 );
                #print "$extension mymac=$1\n";
        }
    }
  }
}
close SIPINFO;



# Now we get the variables to change from the template file
# in one array and keep the entire file in another

open( MODS, "< $polycom_template" );
@xmlfile = <MODS>;
foreach $xml_line (@xmlfile) {
    foreach $mod_me (@mod_vars) {
        if ( $xml_line =~ m{.*($mod_me=\".*?\")}i ) {
            push @mods, $1;
        }
    }
}
close MODS;


# Finally, we go through each extension, and make a new file with the
# extension values from sip-extensions.conf, dumping them in the directory.
# If all specified, do all, otherwise only match the extension argument

foreach $configfile ( sort keys %phone ) {
 if ( ($configfile eq $myexten) || ($myexten eq 'all') ) {
    # Get mymac address
    $mymac="";
    foreach $valuepair ( @{ $phone{$configfile} } ) {
        if ($valuepair =~ m{mymac=(.*)} ) {
                $mymac = $1;
        }
    }
    print "$mymac\n";

    if ($mymac ne "") {
      # Create master directory file
      system("cp $polycom_directory $polycom_dir" . '/' . $mymac . "-directory.xml");

      # Create cfg file
      $newfile = $polycom_dir . '/' . $mymac . ".cfg";
      # Set up text to be able to create a mac.cfg file
      $mysip = '<?xml version="1.0" standalone="yes"?>';
      $mysip = $mysip . '';

      # Write the cfg file out
      open( NEWCFG,"> $newfile" );
      print NEWCFG $mysip;
      close NEWCFG;

      # Write the -setup.cfg file out
      $newfile = $polycom_dir . '/' . $mymac . "-setup.cfg";
      open( NEWCONF, "> $newfile" );
      my @newconfig = ();
      @newconfig = @xmlfile;
      foreach $line (@newconfig) {
        foreach $tothis ( @{ $phone{$configfile} } ) {
            foreach $changethis (@mods) {
                if (
                    substr( $changethis, 0, index( $changethis, "=" ) )
                        eq
                    substr( $tothis, 0, index( $tothis, "=" ) ) )
                {
                    $line =~ s/$changethis/$tothis/g;
                }
            }
        }
        print NEWCONF $line;
      }
      close NEWCONF;
   }
 }
}

exit 0;

RESETTING ALL POLYCOM PHONES ON THIS ASTERISK BOX

Whenever you make changes to the configuration of the phones, you probably want to reset the phones. You can do this by going to each phone and rebooting it. Better is to create a notify command that you can use from the asterisk console to cause a sip extension to receive a message to do something (in this case reboot).

First, we need to get the notify function to work. Once that works, we can use a script to send this message to all workstations listed in sip-extensions.conf.

1. Create a notify command.
nano /etc/asterisk/sip_notify.conf

[polycom-check-cfg]
Event=>check-sync
Content-Length=>0

Save it (ctrl-X)

2. Test notify command
Log into asterisk:
/usr/sbin/asterisk -rvvvvvvvvvvvvvvvvvv
Type command to reset an extension (here I do 1001):
#sip notify polycom-check-cfg 1001

3. Save this script as resetphones, chmod 755, then run it to reset all phone extensions:

#!/usr/bin/perl
# reset all phones listed in the sip-extensions.conf file
$idfile='/etc/asterisk/sip-extensions.conf';
print "Processing $idfile...\n";
my @idlines = ();
open(IDFILE,"< $idfile" ) or die "error opening $idfile";
@idlines = <IDFILE>;
foreach $idline (@idlines) {
    if (substr($idline,0,1) ne ';') {
        if ( $idline =~ m{\[(.*?)\]\s+$}i ) {
          $extension = $1;
          print "$extension\n";
          system ('/usr/sbin/asterisk -rx "' .
                 "sip notify polycom-check-cfg $extension"
                 . '"' . "\n");
        }
    }
}

Incidentally, this script is a great jumping off point for any command you want to issue for all extensions. It picks out the [] blocks of the sip-extensions.conf file and then can issue any arbitrary command by changing the "sip notify polycom-check-cfg $extension" text to the command you want to issue.

Tags

it says the following:

syntax error at ./polycom-reset-all line 7, near "= ;"

polycom-reset-all is the name of the script of course... I change the location of the file that contains the extensions.

Sorry, there was a problem with my website software properly parsing the sample code. It has been fixed.

Same error, different line: 102; the assignment to

@xmlfile = ;

tosses an error.

SuSE 11.0, Perl 5.8.8

I looked in the page source, found the looks-like-an-HTML-tag piece of perl, and pasted it in... and now it runs, but doesn't appear to do anything.

I've modified the pointer to pick up sip_additional.conf, which is where FreePBX/PIAF puts configured extensions, and modified the destination to /tftpboot, which is where SuSE points its TFTP server, but no new files; is there something else I'm likely to need to do, do you think?

Something like that is usually a rights issue or a messed up directory path. You can debug it by printing the values for the dirs and verifying them and that your user can create files in those destinations.

Unless there's another perl-to-html bug...

Did this help you? You can help me!


Did you find this information helpful? You can help me back by linking to this page, purchasing from my sponsors, or posting a comment!


+One me on Google:


Follow me on twitter: http://twitter.com/mojocode







Comments



Affiliation Badges