Ramblings

April Showers

I’m looking out my window right now at my neighbors. They have their kitchen lights on. Inside my house we have light - plenty enough light to light the whole room. And yet I still find it difficult to wrap my head around what just happened.

Read More
PHP

Interview Questions for Programmers

Over the years, I’ve seen a number of blog posts relating to common questions that should be asked of programmers. Obviously, this is going to depend on exactly what position you are hiring for, but there are some good “gateway” questions that can be used to determine whether or not an applicant you are interviewing can … well … even program at all. If they even have the mindset that makes a good developer.

A common one I’ve seen tossed around is Fizz Buzz. The challenge goes something like this:

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

Now, to anyone who even has a basic understanding of programming, this is super simple to solve using a modulus operator. But apparently many people applying for even entry-level development jobs cannot solve this problem. According to the article linked above, even one “senior developer” took 15 minutes to solve this problem.

Earlier today, a friend posted something on Facebook that inspired what I think it another good, intermediate to difficult level programming question that also looks for pattern recognition. The relevant part of the post began by stating: “This year July has 5 Fridays 5 Saturdays and 5 Sundays.” There is the question! It would go something like this:

The month of July 2011 has 5 Fridays, 5 Saturdays and 5 Sundays. Calculate the next 50 times there will be a month that has 5 Fridays, 5 Saturdays and 5 Sundays.

Woah, so how to go about solving this problem? Well, look at a picture of July 2011. Notice something interesting about this month in relation to the question? This month has 31 days (the most any month can have), begins on a Friday and ends on a Sunday. And that’s the solution! It’s any month with 31 days that begins on a Friday!

With this in mind, it’s pretty easy to come up with a PHP solution:

<?php
$count = 0;
$num_found = array();

while(count($num_found) < 50) {
    $count++;
    $ts = strtotime("$count months");

    if(date("t", $ts) == 31 && date("N", strtotime(date("Y-m-01", $ts))) == 5) {
        $num_found[] = date("F Y", $ts);
    }
}

print_r($num_found);
?>

Note that I make use of PHP’s strtotime function, because it is the Swiss Army Knife of date manipulation in PHP. This would need to be adapted for use in another language.

So now tell me: what are some other questions you’ve been asked or asked in an interview?

Read More
Apple

Xcode 4

So today, out of nowhere, Xcode 4 finally landed as an official release. After seemingly forever in beta, and me quipping more than once about it’s similarity to Duke Nukem Forever, Apple finally pulled the trigger and released it. But something changed.

Xcode now has a price. And that has left me, as both a Mac user and a Mac developer, with a lot of questions.

It’s either $4.99 if you’re not a registered, paid Apple developer, or free if you are a registered, paid Apple developer (with all its $99 per year price tag glory). Supposedly there’s some crazy accounting reason that they have to charge for it. This, of course, leaves open the possibility that Xcode will soon be free again once OS X 10.7 arrives. But, it also leaves open the possibility that Xcode will no longer be distributed with OS X and will always have a price tag. It may not even stay $4.99. It may be $49.99 or $499.99.

There are additional questions, too. Does this mean that Apple is still distributing Xcode as a bundle with GNU GCC? Because there are things (such as MacPorts) that rely on the underlying foundation provided by the developer bundle that don’t actually use Xcode. Before, those were completely free. Now, they cost $4.99 unless they have split the underlying compiler from the IDE. And if they are still distributing it with GCC, that leads to all kinds of crazy interesting licensing questions.

But I think the worst part is that there is now a barrier to entry, however low, to being a developer on a platform that is already a minority in market share. I can’t understand how Apple potentially believes that it is good and right to trade short term profits for long term growth in the number of potential developers. For the future of the Mac platform, I sure hope this isn’t their line of reasoning.

So, let me tell you a little story.

My first dabbling in programming came courtesy of QuickBASIC back in the MS-DOS and Windows 3.1 days. This was the late 80s or early 90s, so I would have been 10 or 11 at the time. I stumbled across the Qbasic environment included with MS-DOS by accident and found Nibbles. And, after playing it, I discovered that I could change things by making changes to the strange text presented on the screen. I could change colors and speeds. But it would be a couple of years before I really understood what I was doing.

When Windows 95 came out (and along with it, Visual Basic 4), I talked my parents into getting me a copy. I don’t remember how much it cost but it was probably a lot because it was one of the few Christmas presents I got that year. But boy did I run with it. I’ve periodically felt guilty over that expense because I didn’t actually make anything really useful with it, but it was instrumental in furthering my education. Now I could do things on my computer far beyond what poor ol’ Qbasic was capable of. So I wrote lots of silly little programs. I put together a “family newsletter” one year that was installed and ran as a piece of software. I was pretty proud of that. I even wrote some software for my high school as part of a software development and AP Computer Science courses.

Eventually, I would move on to other things. Other versions of Visual Basic, Java, C, a brief foray into LISP and Forth-based languages for programming MUDs, and eventually web programming. First in Perl, then in PHP. I even landed my first paying programming job while still in high school, writing applications for a local transit contractor. At first, these were Visual Basic applications. But by the time I left (August of 2000) everything was going to the web and so were we.

But I can trace everything - my entire career, and my consuming passion for software engineering - back to Qbasic and Nibbles. A silly little game about a block snake, and a free development environment included with the operating system. Had I not stumbled on Qbasic and Nibbles, there’s a chance I would never have been a developer.

This is not about $4.99. I spend more on coffee in a week than that. My worry is about that 11 year old kid out there somewhere who may never get the opportunity to stumble across Xcode or the sample applications in /Developer and realize the raw power they possess. This is an area where Apple, a company with billions in cash on hand, should be happy to show a loss. It would be to the benefit of their platform, both now and in the future.

One of the great benefits of the Mac platform has been it’s low barriers of entry to developers. Sure, one could argue that the hardware is more expensive (and I could counter-argue that, for the quality of the equipment you are getting a bargain), but the development tools have always been freely available online and included with the machine. You could dabble in programming to your heart’s content. Sure, if you want to put something in the app store(s), you had to pay for admission, but there was nothing stopping you from getting all the way to that point, or even distributing your creations on your own.

But this new trend of charging for the development tools - even if it is a paltry sum - sends, to me, a worrying signal about the course Apple intends to tread. They’ve now moved the gate from the last step to the first step. It’s a course that Microsoft, as above, once tread.

Microsoft? They now give away a version of Visual Studio for free.

Read More
Linux

BASH Quickie: Backing Up MySQL Databases

In some ways, after years of doing programming and scripting, I’m now sort of rediscovering the power of the shell.

Tonight, I was working on my server and remembered that I needed to start backing up my MySQL databases (which you do also … right?). So instead of writing a script to do that, with a little research, I was able to come up with a way to:

  1. Dump each database to a separate SQL file, with a timestamp.

  2. bzip the file.

  3. Keep 5 days worth of backups for each database, rotating the oldest backup off.

Here’s what I came up with:

cd /backup/mysql;
for i in $(mysql -BNe 'show databases' -u root -p<password>); do
    mysqldump -u root -p<password> $i | bzip2 > $i-`date +"%Y%m%d"`.sql.bz2;
    rm -rf $i-`date -d "-5 day" +"%Y%m%d"`.sql.bz2;
done > /dev/null 2>&1

Shoved that in my crontab. Works great. Linux rocks.

Read More
Ramblings

The Revolution Will Be Virtualized

I sit here watching Egyptians partying in Tahrir Square on the Internet. Mostly because Al Jazeera is the only group that hasn’t just totally halfassed the coverage of what has unfolded a half a world away. However, I did flip on CNN to watch some coverage on there.

"No dictator, no invader can hold an imprisoned population by force of arms forever. There is no greater power in the universe than the need for freedom. Against that power, governments and tyrants and armies cannot stand." G'kar, Babylon 5

They interviewed several of the protesters and organizers. All of them young - even relative to me, and I ain’t exactly an old guy - and all of them taking the time to actually thank*for making the revolution possible. What were they thanking? Facebook and Twitter. One guy even said he hoped he could meet Mark Zuckerberg and thank him personally.

"People with a passion can change the world for the better." Steve Jobs

It occurs to me that these are the Digital Natives coming of age and taking power. To these people, the Internet is an integral part of their life, and have no memory a time before using the Internet to communicate. They think nothing of talking to people around the world. They’ve been exposed to worldwide ideas. Social and political borders mean nothing to them. They’re all old ideas. The ideas of their parents.

We are just now beginning to grasp the social ramifications of a worldwide network that connects all people. The Internet is, for lack of a better analogy, like a virus that infects the world’s population. People can access the world’s repository of knowledge, and talk with people around the world with minimal effort. They can organize with minimal effort. This communication infects them with ideas of freedom and a desire to communicate.

Now, to be sure, the Internet didn’t get out there and protest. The Internet didn’t physically stand in Tahrir Square and chant protests against Mubarak. The Internet didn’t take gunshots for freedom. But the Internet and social media did provide the tools and the framework in which the revolution could be organized. People will always be the ones taking action. But the ability to communicate - quickly, efficiently, and massively, in such a way that was unthinkable twenty years ago - is going to completely reshape the way the world works going forward.

Iran was the warmup. Egypt and Tunisia are the warning shots to nations around the world: neglect your people at your own peril.

Now, as for Egypt. The optimist in me hopes for a democratic republic. The pessimist in me fears a military dictatorship or, worse, an Islamic dictatorship. I guess we’ll know soon enough.

Read More
Apple

Automatically Setting Adium IM Status with AppleScript

I have more than 20 various IM accounts set up in Adium on my Macintosh. But during the day, the only one I really want to be active is the one I use for work. The remainder, I want to leave logged in, but showing as away with a warning not to bother me unless it is important. But half the time I forget to set all those accounts as away, or I forget to set the work one as available, or some other issue that would arise out of a manual process interferes and too often it doesn’t get done.

Enter AppleScript. I whipped up a surprisingly easy AppleScript to do just this:

tell application "Adium"
    go away with message "Working. Please do not disturb unless necessary."
    go available first account
end tell

Because the work account is the first one, this makes it easy. It just sets all accounts as away and then sets the work one available. I shove this in my MarcoPolo ruleset to fire when I arrive at the office.

The script to reverse the change when I leave is even easier. This is fired when I leave the office:

tell application "Adium" to go available
Read More
Ramblings

FlightPrep

Those of you who follow me on Twitter might have noticed me railing against a company called FlightPrep. You may be wondering, what exactly is the big deal?

The short of the story is, there were a bunch of websites out there dedicated to flight planning. Some of the best ones (SkyVector, Flyagogo, NACOmatc and, best of all RunwayFinder) allowed you to plot a course overlaying a VFR Chart the same way you would in Google Maps. You could modify your route simply by dragging it about, and click airports along the route to get current weather reports. It was kinda like Google Maps for preflight intelligence.

Well, along comes this company called FlightPrep, who decided they weren’t getting rich enough (just ignore the owner’s $500k boat). So they convinced the USPTO to give them a patent on, bluntly, drawing digital lines on a digitized chart. The filed for the patent in 2005 (after a number of the sites above were already online), but used legal sleight-of-hand to get it backdated to 2001. Eventually, after a number of rejections, they were able to find a friendly clerk and were awarded the patent.

They then immediately lawyered up and started going after all of these free flight planning websites, many of which were simply hobbies of some pilots who also happened to know how to program. They requested that these sites “license the technology” (what a ludicrous thing to say, being that the sites pre-dated FlightPrep’s patent) or face lawsuits with damage claims of $149 per unique IP per month.

So what happened? SkyVector settled and “licensed.” NACOmatic, Flyagogo and RunwayFinder all shut down under threat of lawsuit. They’ve also gone after FlightAware, Jeppesen and the AOPA with no success, so far.

It’s pretty clear that, instead of innovating, they’re litigating. Rather than develop some radical new technology, they’re abusing the patent system in an attempt to corner the market.

Bluntly, I’m pissed because they robbed me of a tool (RunwayFinder) that I loved and that was highly useful for a student pilot.

But, general aviation is a small community, and the backlash against FlightPrep has been a beautiful if small-scale example of what happens when you abuse your target market. Within the course of a week, they’ve become a pariah and the most hated company in general aviation. They had to close off their Facebook page because it was being overrun with people voicing their opinion, and their products are receiving highly negative reviews in all markets.

But, while this is all great, it doesn’t bring back RunwayFinder. Even though Dave from RunwayFinder has decided to fight back, he faces a long uphill climb to have this asinine patent thrown out.

In the end, it’s just sad. As I said, GA is a small community where nobody is getting rich. We’re all supposed to be on the same team.

Read More
Apache

Automatically Provisioning Polycom Phones

The goal of this project were twofold:

  1. 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…

  2. 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:

  1. I create a profile for the phone in the database, then plug the phone in.

  2. 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.

  3. Phone boots with new provisioning information, begins downloading update SIP application and BootROM. Reboots.

  4. 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
Apache

Google Chrome, Mac OS X and Self-Signed SSL Certificates

I’ve been using Google Chrome as my primary browser for the last few months. Sorry, Firefox, but with all the stuff I need to work installed, you’re so slow as to be unusable. Up to and including having to force-quit at the end of the day. Chrome starts and stops quickly But that’s not the purpose of this entry. The purpose is how to live with self-signed SSL certificates and Google Chrome.

Let’s say you have a server with a self-signed HTTP SSL certificate. Every time you hit a page, you get a nasty error message. You ignore it once and it’s fine for that browsing session. But when you restart, it’s back. Unlike Firefox, there’s no easy way to say “yes, I know what I’m doing, ignore this.” This is an oversight I wish Chromium would correct, but until they do, we have to hack our way around it.

Caveat: these instructions are written for Mac OS X. PC instructions will be slightly different at PCs don’t have a keychain, and Google Chrome (unlike Firefox) uses the system keychain.

So here’s how to get Google Chrome to play nicely with your self-signed SSL certificate:

  1. On your web server, copy the crt file (in my case, server.crt) over to your Macintosh. I scp'd it to my Desktop for ease of work.

    ** These directions has been updated. Thanks to Josh below for pointing out a slightly easier way.**

  2. In the address bar, click the little lock with the X. This will bring up a small information screen. Click the button that says “Certificate Information.”

  3. Click and drag the image to your desktop. It looks like a little certificate.

  4. Double-click it. This will bring up the Keychain Access utility. Enter your password to unlock it.

  5. Be sure you add the certificate to the System keychain, not the login keychain. Click “Always Trust,” even though this doesn’t seem to do anything.

  6. After it has been added, double-click it. You may have to authenticate again.

  7. Expand the “Trust” section.

  8. “When using this certificate,” set to “Always Trust”

That’s it! Close Keychain Access and restart Chrome, and your self-signed certificate should be recognized now by the browser.

This is one thing I hope Google/Chromium fixes soon as it should not be this difficult. Self-signed SSL certificates are used **a lot **in the business world, and there should be an easier way for someone who knows what they are doing to be able to ignore this error than copying certificates around and manually adding them to the system keychain.

Read More
Asterisk

Auto Re-Provisioning Polycom Phones

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