Creating a Home Intercom System Using Asterisk and Cheap Used Phones

This is an old post!

This post is over 2 years old. Solutions referenced in this article may no longer be valid. Please consider this when utilizing any information referenced here.

Recently, when my company was moving offices, I had the opportunity to snag a dozen or so used Polycom telephones. Had this idea that I wanted to try and it turned out that it worked pretty well. And that idea was this: what if I could use them to create an intercom system in the house?

Why

Years ago, home intercom systems were a thing in many mid to upper tier homes. You may remember seeing the wall mounted intercoms in each room, usually with a master unit in a common area like the kitchen. Some could even provide radio to some or all of the rooms - like a very primitive Sonos system! They looked something like this:

A NuTone home intercom master unit, by 'Alex V' on Flickr. CC By 2.0
A NuTone home intercom master unit, by 'Alex V' on Flickr. CC By 2.0

You can actually still buy modern versions of these, and they are often options available from high-end homebuilders. Many are wireless these days; some even include video.

In our case, the size of the house tends to mean lots of yelling from room to room. Especially when my daughter may be upstairs in her room with the door closed and we’re downstairs in the bedroom, getting someone’s attention in here can be a bit of a challenge at times.

But just buying something isn’t hacker friendly, not to mention expensive. And, anyways, I needed something fun to hack around on in the evenings for a week or so. It turns out that this works pretty well, although it definitely took some work to get everything set up and going.

The Phones

The phones I acquired were mostly Polycom IP330s, with I think one or two IP331s. These are positively ancient phones but are perfectly suitable for what we are doing here. In my case these were free (I kept them from ending up in a dumpster) but you can get them on eBay for about $20 each right now. So this is a pretty cheap or free experiment.

Install Asterisk

If you just stumbled into this article, you may be wondering what Asterisk is. Asterisk began life as an open-source PBX (Private Branch eXchange), basically a telephone system for businesses. Mark Spencer needed a phone system for his Linux support business, but didn’t want to buy a ridiculously expensive system from someone like 3Com, so he created a software phone system. These days Asterisk is used everywhere from businesses to hotels to telecom carriers themselves.

My first job out of Auburn was as a consultant building telecom systems around Asterisk and various other related technologies. Though I have been out of the telecom game now for a good 16 years, I thought this might be a chance to get back into it and see what all had changes.

First, I tried to do this using FreePBX. And what a disaster that was. I won’t elaborate futher on that other than to say I am not impressed with FreePBX. Let’s use just vanilla Asterisk for this. And to do that, we’re going to build Asterisk from source because what is in the apt tree is probably pretty far out of date.

First, install the dependencies.

$ sudo apt update
$ sudo add-apt-repository universe
$ sudo apt -y install git curl wget libnewt-dev libssl-dev libncurses5-dev libsqlite3-dev build-essential libjansson-dev libxml2-dev  uuid-dev

Next, let’s fetch the Asterisk source code.

$ cd /tmp
$ wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-18-current.tar.gz
$ tar xvf asterisk-18-current.tar.gz
$ cd asterisk-18*/
$ sudo contrib/scripts/install_prereq install

Next, install the MP3 decoder. This is not strictly necessary but if you want to use MP3 music, you’ll need it.

$ contrib/scripts/get_mp3_source.sh

Now, it’s time to build Asterisk itself.

$ ./configure
$ make menuselect

From here you can select any addons you want to have. Unless you know what you are doing the defaults will be fine. The one thing you probably should do is check that you are installing at least one Core Sound package in ULaw.

Now, it’s time to compile.

$ make
$ sudo make install
$ sudo make samples
$ sudo make config
$ sudo ldconfig

Create your user accounts.

$ sudo groupadd asterisk
$ sudo useradd -r -d /var/lib/asterisk -g asterisk asterisk
$ sudo usermod -aG audio,dialout asterisk
$ sudo chown -R asterisk.asterisk /etc/asterisk
$ sudo chown -R asterisk.asterisk /var/{lib,log,spool}/asterisk
$ sudo chown -R asterisk.asterisk /usr/lib/asterisk
$ sudo chmod -R 750 /var/{lib,log,run,spool}/asterisk /usr/lib/asterisk /etc/asterisk

$ sudo vim /etc/default/asterisk
#Uncomment AST_USER and AST_GROUP to look like below
AST_USER="asterisk"
AST_GROUP="asterisk"

$ sudo vim /etc/asterisk/asterisk.conf
runuser = asterisk ; The user to run as.
rungroup = asterisk ; The group to run as.

And finally, install and enable Asterisk.

$ sudo systemctl restart asterisk
$ sudo systemctl enable asterisk

You should now have a working Asterisk install. Most of these instructions came from this article.

Configuring Phone Accounts

Next, we need to start configuring phones to register with Asterisk. First, we’re going to make PJSIP, which is the new SIP package in Asterisk, use .conf.d Debian/Ubuntu style configs.

$ cd /etc/asterisk
$ mkdir pjsip.conf.d
$ echo "#include pjsip.conf.d/*.conf" >> /etc/pjsip.conf

Now, Asterisk will include all the files in /etc/asterisk/pjsip.conf.d. Next, we need to make a configuration for a phone. We’re going to make a template to help us:

$ vim 0000-phoneprov_defaults.conf

And fill it with this data:

[phoneprov_defaults](!)
type=phoneprov
PROFILE=polycom
SERVER=<your server name or IP address>
TIMEZONE=America/Chicago

Next, grab a Polycom and get the MAC address off the back of it. Create a new config file in /etc/asterisk/pjsip.conf.d:

$ vim Office.conf
[103]
type=endpoint
context=default
disallow=all
allow=ulaw
auth=103-auth
outbound_auth=103-auth
transport=transport-udp
aors=103

[103-auth]
type=auth
auth_type=userpass
password=103
username=103

[103]
type=aor
max_contacts=1

[103](phoneprov_defaults)
endpoint=103
MAC=<mac address goes here, all lowercase>
DISPLAY_NAME=Office
LABEL=103 Office
CALLERID=103

Repeat the last step for each phone

Enable Phone Provisioning

Provisioning is the process of telling a phone what config to use to talk to the server. While you can do this manually on each phone, Asterisk has built-in ability to automatically provision phones for you. In some cases this can be done without you even having to touch a phone!

First, edit /etc/asterisk/http.conf and enable the HTTP server:

enabled = yes
bindaddr = 0.0.0.0

Then, edit /etc/asterisk/manager.conf and enable the management interface and web interface:

[general]
enabled = yes
webenabled = yes

Next, you will need to fetch the Polycom firmare. As the phones I am using are discontinued, there are no links on the Polycom website to download old firmware. But, fortunately, all they did was remove the links so you can still fetch them:

$ mkdir -p /var/lib/asterisk/phoneprov/configs
$ cd /var/lib/asterisk/phoneprov/configs
$ wget https://downloads.polycom.com/voice/voip/uc/Polycom_UC_Software_3_3_5_release_sig_combined.zip --no-check-certificate
$ wget https://downloads.polycom.com/voice/voip/uc/Polycom_UC_Software_3_3_5_release_sig_split.zip --no-check-certificate
$ unar -D Polycom*
$ rm -rf *.zip

The phones I am using, mostly Polycom IP-330s, this is the most recent firmware they support. The IP-331s support a slightly newer version, but I wanted to just have everyone on the same version to reduce potential troubleshooting problems. So everyone gets firmware version 3.3.5.

The next step will depend on what you are running at home for your network DHCP server. Polycom phones will look at certain DHCP options for hands-off configuring. So you will need to configure your DHCP server to send the following options:

  • Option 160: http://<server IP or host name>:8080/phoneprov/
  • Option 101: America/Chicago (or your timezone)
  • Option 100: CST6CDT,M3.2.0,M11.1.0 (or your time code)

Give Asterisk a restart to be sure everything is updated:

$ systemctl restart asterisk

Finally, test out your config by pointing your browser to http://<server IP or host name>:8080/phoneprov/<your phone mac address>.cfg. If you see some XML, everything is working!

Factory Resetting Polycom Phones

If you are lucky, your phone will automatically download the latest config from your Asterisk server and restart in a clean config. But if your phone was locked down by its previous owner you will need to factory reset them. This article was very helpful and even included a tool that gives you the exact key presses you will need to enter to reset it.

Creating the Intercom System

So, now we have phones configured and registered with Asterisk, we can finally start actually building the intercom. There’s several ways you can do this. In my case, because I eventually intend to also hook these phones up to a SIP provider, I am going to create a queue. Eventually the queue will seve as an entry point for outside callers, but its members will also be the devices that are part of the intercom.

Like above, we are going to create a .conf.d directory:

$ mkdir -p /etc/asterisk/queues.conf.d
$ echo "#tryinclude queues.conf.d/*.conf" >> /etc/asterisk/queues.conf
$ cd /etc/asterisk/queues.conf.d
$ vim default.conf

Now, inside this file we will add all the phones:

[default]
strategy = ringall
timeout = 10
retry = 5
maxlen = 1
joinempty = yes
leavewhenempty = no
context = default
periodic-announce-frequency = 60
periodic-announce = calling

member => PJSIP/101
member => PJSIP/102
# Add each member here

Next, we are going to update our dialplan. The dialplan is pretty much the core of Asterisk. It tells Asterisk what steps to take when it receives a call.

First, again, we’re going to do the .conf.d thing:

$ mkdir -p /etc/asterisk/extensions.conf.d
$ vim /etc/asterisk/extensions.conf

Now, I would suggest you remove just about everything in this file where the large block comments at the top end. Then add this:

#include extensions.conf.d/*.conf

Then, create a new file:

$ vim /etc/asterisk/extensions.conf.d/default.conf

Below is the dialplan I have configured. I have added inline comments to explain what is happening:

; Default is the context. Calls coming into Asterisk start in a context. If you
; reference above where we said context=default in the PJSIP phone configs, this
; is what that does.
[default]

; This is the "operator" extension. It places the caller in a queue, that rings
; all the phones until someone answers, like a traditional house phone.
exten => 0,1,Answer
exten => 0,n,Wait(1)
exten => 0,n,Queue(default)

; Extension 0000 is going to be our full house intercom extension. What we're
; doing here is using a little Asterisk variable magic to fetch the queue
; members and convert them to a SIP dial string. If you were just paging a
; single phone, it would be something like Page(PJSIP/101). Multiple phones are
; concatenated with an &. So the end result is like Page(PJSIP/101&PJSIP/102)

; We also have a macro that adds a special header to the SIP call. We'll get to
; that in a bit, but that's what the b(ring-answer^addheader^1) does.
exten => 0000,1,Answer
exten => 0000,n,Wait(1)
exten => 0000,n,Page(${STRREPLACE(QUEUE_MEMBER_LIST(default),",","&")},b(ring-answer^addheader^1))

; This lets us intercom specific phones by dialing 0000 + an extension. So
; 0000101 for the office. Same with the ring header.
exten => _0000[12]XX,1,Answer
exten => _0000[12]XX,n,Wait(1)
exten => _0000[12]XX,n,Page(PJSIP/${EXTEN:4},b(ring-answer^addheader^1))

; This is a standard direct-dial phone to phone call.
exten => _[12]XX,1,Dial(PJSIP/${EXTEN})

; This macro is key. Polycom phones have the ability to automatically answer if
; a specific SIP header is sent. This adds that header. We will configure the
; Polycoms to answer on this header below.
[ring-answer]
exten => addheader,1,Set(PJSIP_HEADER(add,Alert-Info)=Paging)
exten => addheader,n,Return

So, give Asterisk a restart:

$ sudo systemctl restart asterisk

And try placing a phone-to-phone call. Hopefully that should work!

Configuring Polycom Auto Answer

Wow, this has been a journey! I applaud you for sticking with this; it took me several evenings of work to muddle my way through this with just enough telecom knowledge from my previous job (16 years ago…) and remembering all the stuff I forgot about Asterisk. But we’re almost there.

As I mentioned above, Polycom phones have the ability to automatically answer if a specific SIP header is sent. We are now sending those headers, so we need to configure the phones to receive it.

Open up the Polycom sip.cfg file:

$ vim /var/lib/asterisk/phoneprov/configs/sip.cfg

It’s a giant pile of XML vomit, but you’ll need to navigate down the following path: polycomConfig -> voIpProt -> SIP and add the following XML:

<alertInfo
    voIpProt.SIP.alertInfo.1.value="Paging"
    voIpProt.SIP.alertInfo.1.class="custom1" />

Next, where the </voipProt> tag closes, add this:

<se.rt>
    <se.rt.custom1
        se.rt.custom1.name="Paging"
        se.rt.custom1.ringer="ringer15"
        se.rt.custom1.timeout="800"
        se.rt.custom1.type="ring-answer">
    </se.rt.custom1>
    <se.rt.default se.rt.default.timeout="5000">
    </se.rt.default>
</se.rt>

Restart your phones and try dialing 0000. If everything works, the other phone(s) should automatically pick up.

Adding an Intercom Soft Button

The Polycom IP330 has three “soft buttons” that can be defined by configuration. Next, we are going to replace the rather-pointless “NewCall” soft button with a much more functional “Intrcom” button.

Open up the Polycom sip.cfg file:

$ vim /var/lib/asterisk/phoneprov/configs/sip.cfg

Navigate back down to polycomConfig -> voIpProt -> SIP. Add the following XML:

<feature
    feature.directedCallPickup.enabled="1"
    feature.enhancedFeatureKeys.enabled="1" />

<softkey
    softkey.1.label="Intrcom"
    softkey.1.action="$FLine1$0000$Tinvite$"
    softkey.1.enable="1"
    softkey.1.use.idle="1"
    softkey.2.label="Intrcom"
    softkey.2.action="$FLine1$$FDialpad0$$FDialpad0$$FDialpad0$$FDialpad0$$Tinvite$"
    softkey.2.enable="1"
    softkey.2.use.dialtone="1"
    softkey.feature.newcall="0"
    softkey.feature.endcall="0" />

So let’s go through what we’re doing here:

  • Enabling enhancedFeatureKeys. This is required to allow us to define our own softkeys.

  • softkey.1.* creates an “Intrcom” key that dials a call when the phone is idle. This means when the receiver is on the hook and the speakerphone is off.

  • We’ll take apart $FLine1$0000$Tinvite$:

    • $FLine1$ Selects phone line 1. The Polycom IP-330 supports two lines.
    • 0000 sends 4 zeros.
    • $Tinvite$ sends a SIP invite - basically connects the call.

  • softkey.2.* creates an “Intrcom” key that dials a call when the phone is sending dialtone. Like when you have picked up the receiver or pressed the speakerphone button. Why does this have to be a separate config? Your guess is as good as mine but I could not get it to work with a single key. I got errors when I tried to use the “Intrcom” key with the receiver off, but this works.

  • We’ll take apart $FLine1$$FDialpad0$...:

    • $FLine1$ Selects phone line 1.
    • $FDialpad0$... manually triggers the 0 dialpad key. This is necessary. Trying the 0000 trick above does not work.
    • $Tinvite$ connects the call.

  • softkey.feature.newcall="0" disables the “NewCall” button.

  • softkey.feature.endcall="0" disables the “EndCall” button.

So now, with a single button press, you can intercom all the phones in the house! It all actually works!

Conclusions

This was a fun experiment and a great way to recycle some old phones that were going to be thrown away into something useful at home. And from here, with a standard Asterisk install, you have all the usual possibilities that gives you. My next step will be to find a cheap SIP provider and maybe we’ll actually have a “home phone” again for the first time in ages. But even without that, it’s useful just as an intercom alone.

Presentation

Interested in learning more about this article? I recently gave a talk about my experience building the intercom and using Asterisk at home. Feel free to check it out and watch the video:

Comments (0)

Interested in why you can't leave comments on my blog? Read the article about why comments are uniquely terrible and need to die. If you are still interested in commenting on this article, feel free to reach out to me directly and/or share it on social media.

Contact Me
Share It
Apache
The goal of this project were twofold: To completely eliminate the need for me to touch the phone to provision it. I want to be able to create a profile for it in the database, then simply plug the phone in and let it do the rest. And… To eliminate per-phone physical configuration files stored on the server. The configuration files should be generated on the fly when the phone requests them. So the flow of what happens is this: I create a profile for the phone in the database, then plug the phone in. Phone boots initially, receives server from DHCP option 66. Script on the server hands out the correct provisioning path for that model of phone. Reboots with new provisioning information. Phone boots with new provisioning information, begins downloading update SIP application and BootROM. Reboots. Phone boots again, connects to Asterisk. At this rate, provisioning a phone for a new employee is simply me entering the new extension and MAC address into an admin screen, and giving them the phone. It’s pretty neat. **Note: **there are some areas where this is intentionally vague, as I’ve tried to avoid revealing too much about our private corporate administrative structure. If something here doesn’t make sense or you’re curious, post a comment. I’ll answer as best I can. Creating the initial configs I used the standard download of firmware and configs from Polycom to seed a base directory. This directory, on my server, is /www/asterisk/prov/polycom_ipXXX, where XXX in the phone model. Right now we deploy the IP-330, IP-331 and IP-4000. While right now the IP-330 and IP-331 can use the same firmware and configs, since the IP-330 has been discontinued they will probably diverge sometime in the not too near future. With the base configs in place, this is where mod_rewrite comes into play. I added the following rewrite rules to the Apache configs: RewriteEngine on RewriteRule ^/000000000000\.cfg /index.php RewriteRule /prov/[^/]+/([^/]+)-phone\.cfg /provision.php?mac=$1 [L] RewriteRule /prov/polycom_[^/]+/[^/]+-directory\.xml /prov/polycom_directory.php` RewriteCond %{THE_REQUEST} ^PUT* RewriteRule /prov/[^/]+/([^/]+)\.log /prov/polycom_log.php?file=$1` To understand what these do, you will need to take apart the anatomy of a Polycom boot request. It requests the following files in this order: whichever bootrom.ld image it’s using, [mac-address].cfg if it exists or 000000000000.cfg otherwise, the sip.ld image, [mac-address]-phone.cfg, [mac-address]-web.cfg, and [mac-address]-directory.xml. So, we’re going to rewrite some of these requests to our scripts instead. Generating configs on the fly We’re going to skip the first rewrite rule (we’ll talk about that one in a little bit since it has to do with plug-in auto provisioning). The one we’re concerned with is the next one, which rewrites [mac-address]-phone.cfg requests to our provisioning script. So each request to that file is actually rewritten to provision.php?mac=[mac-address]. Now, in the database, we’re keeping track of what kind of phone it is (an IP-330, IP-331 or IP-4000), so when a request hits the script, we look up in the database what kind of phone we’re dealing with based on the MAC address, and use the variables from the database to fill in a template file containing exactly what that phone needs to configure itself. For example, the base template file for the IP-330 looks something like this: <sip> <userinfo> <server <?php foreach($phone as $key => $p) { ?> voIpProt.server.<?php echo $key+1 ?>.address="<?php echo $p["host"] ?>" voIpProt.server.<?php echo $key+1 ?>.expires="3600" voIpProt.server.<?php echo $key+1 ?>.transport="UDPOnly" <?php } ?> /> <reg <?php foreach($phone as $key => $p) { ?> reg.<?php echo $key+1 ?>.displayName="<?php echo $p["first_name"] ?> <?php echo $p["last_name"] ?>" reg.<?php echo $key+1 ?>.address="<?php echo $p["name"] ?>" reg.<?php echo $key+1 ?>.type="private" reg.<?php echo $key+1 ?>.auth.password="<?php echo $p["secret"] ?>" reg.<?php echo $key+1 ?>.auth.userId="<?php echo $p["name"] ?>" reg.<?php echo $key+1 ?>.label="<?php echo $p["first_name"] ?> <?php echo $p["last_name"] ?>" reg.<?php echo $key+1 ?>.server.1.register="1" reg.<?php echo $key+1 ?>.server.1.address="<?php echo $p["host"] ?>" reg.<?php echo $key+1 ?>.server.1.port="5060" reg.<?php echo $key+1 ?>.server.1.expires="3600" reg.<?php echo $key+1 ?>.server.1.transport="UDPOnly" <?php } ?> /> </userinfo> <tcpIpApp> <sntp tcpIpApp.sntp.address="pool.ntp.org" tcpIpApp.sntp.gmtOffset="<?php echo $tz ?>" /> </tcpIpApp> </sip> The script outputs this when the phone requests it. Voila. Magic configuration from the database. There’s a little bit more to it than this. A lot of the settings custom to the company and shared among the various phones are in a master dealnews.cfg file, and included with each phone (it was added to the 000000000000.cfg file). Now, on to the next rule. Generating the company directory Polycom phones support directories. There’s a way to get this to work with LDAP, but I haven’t tackled that yet. So, for now, we generate those dynamically as well when the phone requests any of its *-directory.xml files. This one’s pretty easy since 1) we don’t allow the endpoints to customize their directories (yet), and 2) because every phone has the same directory. So all of those requests go to a script that outputs the XML structure for the directory: <directory> <item_list> <?php if(!empty($extensions)) { foreach($extensions as $key => $ext) { ?> <item> <fn><?php echo $ext["first_name"]?></fn> <ln><?php echo $ext["last_name"]?></ln> <ct><?php echo $ext["mailbox"]?></ct> </item> <?php } ?> <? } ?> </item_list> </directory> We do this for both the 000000000000-directory.xml and the [mac-address]-directory.xml file because one is requested at initial boot (the 000000000000-directory.xml file is intended to be a “seed” directory), whereas subsequent requests are for the MAC address specific file. Getting the log files Polycoms log, and occasionally the logs are useful for debug purposes. The phones, by default, will try to upload these logs (using PUT requests if you’re provisioning via HTTP like we are). But having the phone fill up a directory full of logs is ungainly. Wouldn’t it be better to parse that into the database, where it can be easily queried? And because the log files have standardized names ([mac-address]-boot/app/flash.log), we know what phone they came from.Well, that’s what the last two rewrite lines do. We rewrite those PUT requests to a PHP script and parse the data off stdin, adding it to the database. A little warning about this. Even at low settings Polycom phones are chatty with their logs. You may want to have some kind of cleaning script to remove log entries over X days old. Passing the initial config via DHCP At this point, we have a working magic configuration. Phones, once configured, fetch dynamically-generated configuration files that are guaranteed to be as up-to-date as possible. Their directories are generated out of the same database, and log files are added back to the same database. It all works well! … except that it still requires me to touch the phone. I’m still required to punch into the keypad the provisioning directory to get it going. That sucks. But there’s a way around that too! By default, Polycom phones out of the box look for a provisioning server on DHCP option 66. If they don’t find this, they will proceed to boot the default profile thats ships with the phone. It’s worth noting that, if you don’t pass it in the form of a fully-qualified URL, it will default to TFTP. But you can pass any format you can add to the phone. if substring(hardware, 1, 3) = 00:04:f2 { option tftp-server-name "http://server.com"; } In this case, what we’ve done is look for a MAC address in Polycom’s space (00:04:f2) and pass it option 66 with our boot server. But, we’re passing the same thing no matter what kind of phone it is! How can we tell them apart, especially since, at this point, we don’t know the MAC address. The first rewrite rule handles part of this for us. When the phone receives the server from option 66 and requests 000000000000.cfg from the root directory, we instead forward it on to our index.php file, which handles the initial configuration. Our script looks at the HTTP_USER_AGENT, which tells us what kind of phone we’re dealing with (they’ll contain strings such as “SPIP_330”, “SPIP_331” or “SSIP_4000”). Using that, we selectively give it an initial configuration that tells it the RIGHT place to look. <?php ob_start(); if(stristr($_SERVER['HTTP_USER_AGENT'], "SPIP_330")) { include "devices/polycom_ip330_initial.php"; } if(stristr($_SERVER['HTTP_USER_AGENT'], "SPIP_331")) { include "devices/polycom_ip331_initial.php"; } if(stristr($_SERVER['HTTP_USER_AGENT'], "SSIP_4000")) { include "devices/polycom_ip4000_initial.php"; } $contents = ob_get_contents(); ob_end_clean(); echo $contents; ?> These files all contain a variation of my previous auto-provisioning configuration config, which tells it the proper directory to look in for phone-specific configuration. Now, all you do is plug the phone in, and everything else just happens. A phone admin’s dream. Keeping things up to date By default, the phones won’t check to see if there’s new config or updated firmware until you tell them to. But his also means that some things, especially directory changes, won’t get picked up with any regularity. A quick change to the configs makes it possible to schedule the phones to look for changes at a certain time: <provisioning prov.polling.enabled="1" prov.polling.mode="abs" prov.polling.period="86400" prov.polling.time="01:00" /> This causes the phones to look for new configs at 1AM each morning and do whatever they have to with them. Conclusions The reason all this is possible is because Polycom’s files are 1) easily manipulatable XML, as opposed to the binary configurations used by other manufacturers, and 2) distributed, so that you only need to actually send what you need set, and the phone can get the rest from the defaults. In practice this all works very well, and cut the time it used to take me to configure a phone from 5-10 minutes to about 30 seconds. Basically, as long as it takes me to get the phone off the shelf and punch the MAC address into the admin GUI I wrote. I don’t even need to take it out of the box!
Read More
Asterisk
At dealnews, as I’ve written before, we run Asterisk as our telephone system. I find it to be a pretty good solution to our telecom needs: we have multiple offices and several home-based users. And, for the most part, for hard telephones, we use Polycoms. We run mostly IP-330s, with a couple of IP-4000s and a few new IP-331s. We also have softphones, a couple of PAP2s and a couple of old Grandstreams from our original Asterisk deployment in 2007 that I’m desperately trying to get out of circulation. But it’s mostly Polycoms. Recently, I changed how we were doing provisioning. I’ll write a more in-depth post about this later, but the short of it is that since Polycom phones use XML for their configuration information, we now generate them dynamically instead of creating a configuration file. It’s what I should have done back in 2007 when we bought our first round of Polycoms. But this presented me with a problem: how do I re-provision the older phones - some of which I don’t have easy physical access to (at least that doesn’t involve an airplane ride) - to use the new configuration system? In doing some research, I discovered that Polycom allows you to set, via certain commands, the provisioning server from within a config. With this information, I crafted a custom re-provisioning config that looks like this: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <deviceSettings> <device device.set="1" device.dhcp.bootSrvUseOpt.set="1" device.dhcp.bootSrvUseOpt="2" device.net.cdpEnabled.set="1" device.net.cdpEnabled="0" device.prov.serverType.set="1" device.prov.serverType="2" device.prov.serverName.set="1" device.prov.serverName="server"/> </deviceSettings> And included it at the top of the 000000000000.cfg file (one of the default files downloaded by each Polycom phone): <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <APPLICATION APP_FILE_PATH="sip.ld" CONFIG_FILES="update.cfg, phone1.cfg, sip.cfg" MISC_FILES="" LOG_FILE_DIRECTORY="" OVERRIDES_DIRECTORY="" CONTACTS_DIRECTORY=""/> Then, using Asterisk, I issue the check-config command: asterisk*CLI> sip notify polycom-check-cfg peer The phone should reboot, pick up its new config, then reboot again with with proper new provisioning information from the new provisioning provider. Next post, I’ll show you how to use PHP and mod_rewrite to eliminate the need for per-phone config files.
Read More