Bulk Linksys SPA9*2 Provisioning

At work we have, almost exclusively, the Linksys SPA942 and SPA962 w/ 932 (button attendant) SIP desk phones. We use these in combination with several PBX In a Flash Asterisk servers to do telephony. It works. They (the phones) work. They’re not the best phones in terms of Asterisk compatibility or customisation. But the majority of my fellow staff only want a phone that makes calls; and for that the SPA9*2 works fine.

Until yesterday though each phone was individually configured using the built in web interface. Which is obviously a pain when you need to change something. For example: Each line (i.e. extension although an extension can have multiple line/channels simultaneously) in the phones has a dial plan. By default it looks something like this:
(*xx|[3469]11|0|00|[2-9]xxxxxx|1xxx[2-9]xxxxxxS0|xxxxxxxxxxxx.)
I can’t remember but I think I added the last bit.

Anyway, for those familiar with Asterisk, you’ll know, that the Day/Night module provides *XXX feature codes to toggle between day and night. With out going into it; the above dial plan doesn’t allow the phones to dial *XXX but only *XX. Which means when we started using the Day/Night functionality I had to change the dial plan of every phone. So it’s a pain having them manually configured.

So after Googling and using a bit of nouse I have them all being provisioned with xml configuration files by tftp servers in each of our offices.

If you’re reading this and you have one Asterisk server in one office with all your phones then your Asterisk server can be your phone tftp server and, if you’re lucky, you might be able to use the builtin config manager for your phone. Which is what most of the posts on the interwebs seem to deal with. But seriously, who only has one office?

Down and dirty:

If you look at http://_phone_ip_address/admin/spacfg.xml you’ll get an xml config file as a template to work from. If you scroll down a bit, actually it’s about half way, you’ll find something like the following:
<Profile_Rule group="Provisioning/Configuration_Profile">/spa$PSN.cfg</Profile_Rule>
<Profile_Rule_B group="Provisioning/Configuration_Profile"/>
<Profile_Rule_C group="Provisioning/Configuration_Profile"/>
<Profile_Rule_D group="Provisioning/Configuration_Profile"/>

Each SPA9*2 can be provisioned using settings from up to 4 config files. The settings are persistent over reboot; and you can configure, with Resync_Periodic, how often the settings are re-sync’d from the files. Obviously if you firmware reset the phone the settings vanish. Which, when configuring this way, is a nice way to test your stuff.

Before we go on: If you leave a setting out of the “total” xml configuration the phone uses it’s last known value, which if they’re factory new, or you factory reset, is the default. A setting provided twice uses the last loaded value.

Anyone who has dealt with any form of mass provisioning will recognise the flexibility given here. You can break your configuration up into generic and specific parts. In my case I have 3 levels:

  1. Initial phone provisioning (example below) which simply upgrades the firmware if necessary and directs the phone to “the real” configuration file, which is:
  2. Generic settings such as the voicemail number, feature activation/deactivation codes, dial plans for lines, which extension/lines to activate, etc…
  3. Specific settings for the device such as it’s device id (similar to username) and device secret (password). We also have a few phones that need 3 distinct lines, I use this file to over write #2 settings to do this.

Here is my #1 file:
<flat-profile>
<Profile_Rule ua="na">tftp://172.27.1.1/SPA$PSN-GENERIC.xml</Profile_Rule>
<Resync_Periodic ua="na">5</Resync_Periodic>
<Upgrade_Enable group="Provisioning/Firmware_Upgrade">Yes</Upgrade_Enable>
<Upgrade_Error_Retry_Delay group="Provisioning/Firmware_Upgrade">120</Upgrade_Error_Retry_Delay>
<Upgrade_Rule group="Provisioning/Firmware_Upgrade">tftp://172.27.1.1/SPA$PSN-6-1-3a.bin</Upgrade_Rule>
</flat-profile>

I’ve left the tftp server IP in the above for syntactic example – make sure you replace it with your servers address.

I’ll explain this file next, but first, by default (i.e. factory settings), the phones look for a file /spa$PSN.cfg (where $PSN is 942 or 962 respectively) on the tftp server. Notice it is in the ROOT directory, not in /tftpboot or similar. This got me for a second, the phones DO NOT, I must stress, error out if they can’t find the config file(s) they just use last known values. And the tftp server I was using atftpd doesn’t log file not found unless you turn its verbosity up. Also remember some tftp servers are case sensitive – others are not. That will be especially important when we get to MAC addresses below.

The contents of the file:

  • Profile_Rule: Where to find the phones configuration profile file; note it does not have to be the same file – I am telling the phone to sync to SPA$PSN-GENERIC.xml (which you’ll see below and is my #2 file) from inside /spa$PSN.cfg.
  • Resync_Periodic: How often to resync the settings. In seconds. Please make sure you set this to something sensible in your generic or specific files. The phone semi-deregisters itself when checking for changes to the config file. Depending on how often you intend to make changes 86400 (a day) is probably fine.
  • Upgrade_Enable: Should the phone accept firmware upgrades.
  • Upgrade_Error_Retry_Delay: Seconds before retry if there is an error.
  • Upgrade_Rule: The location to find upgrade firmware. Note that the phone will only upgrade on a factory reset or if the Upgrade_Rule specifies a newer firmware; so you can leave this rule in your file and all phones connected will upgrade when they’re first powered on. When a new firmware is released over write the Upgrade_Rule in your test device specific file and voila it will upgrade on next resync – or if you want to speed things along factory reset the phone or go to http://_phone_ip_address/admin/resync?tftp://…/path/to/config.xml in your browser.

My SPA$PSN-GENERIC.xml file is basically a factory default template with anything that I have set on all phones changed and everything else removed so that it assumes last known value / defaults. Even with my best efforts this still left 150 odd lines in the file. So it does take a bit of work. In hindsight get the factory defaults first; then use the web interface to configure a phone and use diff to get the changes. Split the changes up into generic and specific and you’ll be done. I did it the hard way and went through the xml file. Your choice :)

The important part to the generic file is the profile rules:
<Profile_Rule group="Provisioning/Configuration_Profile">/SPA$PSN-GENERIC.xml</Profile_Rule>
<Profile_Rule_B group="Provisioning/Configuration_Profile">/SPA$PSN-$MA.xml</Profile_Rule_B>

The $MA “variable” is replaced with the MAC address of the phone. Supposedly you can use the $SN serial number too. But I think MAC makes more sense.

And then in /SPA$PSN-$MA.xml I have:
<flat-profile>
<Host_Name group="Info/System_Information">HOST NAME</Host_Name>
<Time_Zone group="Regional/Miscellaneous">GMT+10:00</Time_Zone>
<Time_Offset__HH_mm_ group="Regional/Miscellaneous">01/00</Time_Offset__HH_mm_>
<Station_Name group="Phone/General">STATION NAME</Station_Name>
<Text_Logo group="Phone/General">BOOT TEXT LOGO</Text_Logo>
<Display_Name_1_ group="Ext_1/Subscriber_Information">STATION NAME</Display_Name_1_>
<User_ID_1_ group="Ext_1/Subscriber_Information">DEVICE ID</User_ID_1_>
<Password_1_ group="Ext_1/Subscriber_Information">DEVICE SECRET</Password_1_>
<Display_Name_2_ group="Ext_2/Subscriber_Information">PRVT</Display_Name_2_>
<User_ID_2_ group="Ext_2/Subscriber_Information">DEVICE ID</User_ID_2_>
<Password_2_ group="Ext_2/Subscriber_Information">DEVICE SECRET</Password_2_>
<Ringer_Volume group="User/Audio_Volume">8</Ringer_Volume>
<Speaker_Volume group="User/Audio_Volume">8</Speaker_Volume>
<Handset_Volume group="User/Audio_Volume">10</Handset_Volume>
<Headset_Volume group="User/Audio_Volume">10</Headset_Volume>
<LCD_Contrast group="User/Audio_Volume">8</LCD_Contrast>
<Back_Light_Timer group="User/Audio_Volume">10 s</Back_Light_Timer>
</flat-profile>

And that’s about it for the xml configuration files. Now it’s time to setup tftp to serve the files. I’m not going to walk you through configuring a tftp server – that has been done. Once you have a tftp server setup copy your files into the appropriate location. Remember /spa$PSN.cfg must be in the root directory.

After that’s done you need to tell the phones to use tftp to get their config. You have two options here: 1) Manually using http://_phone_ip_address_/admin/resync?tftp://…/spa942.cfg or similar; or 2) Automagically with DHCP. I prefer option 2 as it lets you add new phones with minimal fuss and also allows factory resets / firmware upgrades (which MAY factory reset the device).

To do that you need to to pass Option 66 from your DHCP server to the phone when it requests an IP. Under Windows server right-click -> Configure Options and scroll down to 066; check the box and specify the IP or name of your tftp server. Just the IP or name. Don’t put tftp:// or the path to the file. Under bind use the next-server AND the tftp-server-name options. You should configure this at a Scope or Group (respectively) level. If you can.

See man dhcpd.conf and man dhcp-options (under ubuntu).

Now go factory reset your phone and it should all work. If not check your tftp logs to make sure the files are served correctly. Remember some tftp servers are case sensitive: What did you use as the MAC address? Also be patient. The phones take around a minute after factory reset to grab /spa$PSN.cfg. And then they’ll need to reboot a few times.

A few more things you can and can’t do:

  1. The DHCP nerds will know there is also an option to specify a boot file. It doesn’t work. The phones are by factory default configured to look for /spa$PSN.cfg and DHCP can’t over write that. At least at the moment.
  2. Take 75% of the settings out of the #3 config file and put them in the generic one. Things like the Text_Logo, Time Zone, Volumes could all be generic; or you could have an extra level where you configure those settings at a office level. Originally that was my plan. But I’ve found that each staff member likes a different volume and that different parts of each office like their phones to report the time as per the clock on the wall. So… I’ve made them device level settings.
  3. You’ll notice I’ve used PRVT as the Display_Name_2_ value. And “STATION NAME” in _1_. These values are what display down the side of the phone next to the “line” keys. All our phones have a private (i.e. PRVT) line for making calls with out a caller id. This also serves to provide each physical desk in the office with an extension irrespective of the current user of the phone. If you don’t need this level of configuration you can scale it back.

Hopefully this is useful. And hopefully I’ve used the right key words to make it easy to find. Because I got my best results when Googling spa$PSN.cfg specifically this how to which got me started with the basics for file #1 and is an interesting method for managing your devices.

Personally I don’t thing spa$PSN.cfg is an intuitive search term for this topic.