Configure a Cisco 7960 phone for use with Asterisk

This one’s sure to get some hits from Google.

First, if you need to upgrade the phone’s firmware, follow the directions on this page at Cisco. The phones come from Cisco configured to use SCCP instead of SIP, and you’ll almost always want to change the firmware. If you know what you’re doing, you’ll have that done in an hour. I read all these posts from people getting confused and agonizing over the firmware upgrade; 90% of their problems could have been avoided by following that document to the letter.

Anyway, once the phone’s firmware is upgraded you should do a factory reset on the phone. To do that, reboot it by pushing * + Settings + 6 together. As soon as the reboot starts, hold down the # key. After a second it will come up with a message about the factory reset key being detected. Type 123456789*0# and it will ask if you want to keep network settings. Push 2 for no.

Now your phone is wiped out. Most of the configuration files are detailed extensively elsewhere, but the important ones are SIPDefault.cnf and SIP<mac address>.cnf where <mac address> is of course the MAC address of your phone in uppercase. Here’s what you can get away with as a bare minimum (note that these directives can be put in either file, as far as I know):

image_version: "P0S3-07-4-00" ; your firmware image file
proxy1_address: "asterisk.example.com" ; you can put an ip address in as well
proxy_register: 1 ; you can't take incoming calls if you aren't registered
nat_enable: 1 ; obviously don't use this if you're not behind NAT
nat_received_processing: 1 ; same as the last one
telnet_level: 2 ; to get access to all functions in the telnet shell

line1_name: "username" ; your asterisk username from sip.conf
line1_authname: "username" ; this will be the same 99% of the time
line1_password: "secret" ; also from sip.conf
user_info: "none" ; I'm not 100% certain this is necessary

Something important to note is that these values get saved in the phone. That’s why we did the reset. If you don’t explicitly set a value to be empty (“”) it will use the value already in the phone, not the default value.

I spent a day getting “401 Unauthorized” messages back from Asterisk before I added those 2 NAT settings. I’m not sure what the problem was, because Asterisk was getting registration requests from the phone, but for some reason it was responding with 401 until I changes settings on the phone.

I’ll add for the record that getting into the phone via telnet can be very useful. The default password is “cisco” and debug sip-messages followed by register 1 1 is your friend. Also, erase protflash will remove all the setting stored in flash memory, forcing the phone to reget the settings from TFTP. Much better than doing a reboot to reload the config files.

bad code

Today I replaced this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<tr>
  <td height="1">
    <table width="347" height="1" border="0" cellpadding="0" cellspacing="0" background="CCorner/images/dot_hor.gif">
      <tr>
        <td width="347" height="1"><img src="images/en/spacer.gif" width="1" height="1"/></td>
      </tr>
    </table>
  </td>
  <td>
    <table width="1" height="22" border="0" cellpadding="0" cellspacing="0" background="CCorner/images/dot_vert.gif">
      <tr>
        <td width="1" height="22"><img src="images/en/spacer.gif" width="1" height="1" alt=""/></td>
      </tr>
    </table>
  </td>
</tr>

<tr> <td height="1"> <table width="347" height="1" border="0" cellpadding="0" cellspacing="0" background="CCorner/images/dot_hor.gif"> <tr> <td width="347" height="1"><img src="images/en/spacer.gif" width="1" height="1"/></td> </tr> </table> </td> <td> <table width="1" height="22" border="0" cellpadding="0" cellspacing="0" background="CCorner/images/dot_vert.gif"> <tr> <td width="1" height="22"><img src="images/en/spacer.gif" width="1" height="1" alt=""/></td> </tr> </table> </td> </tr>

with this:

1
2
3
4
5
6
<tr>
  <td height="1" width="347" style="background:url(CCorner/images/dot_hor.gif)"></td>
</tr>
<tr>
  <td width="1" height="22" style="background:url(../CCorner/images/dot_vert.gif)"></td>
</tr>

<tr> <td height="1" width="347" style="background:url(CCorner/images/dot_hor.gif)"></td> </tr> <tr> <td width="1" height="22" style="background:url(../CCorner/images/dot_vert.gif)"></td> </tr>

But I still feel icky.

More sortable tables

That script again. I needed to be able to trigger a sort onload. Posted this to the aforementioned blog as well, but I’ll keep it here for myself.

1
2
3
4
5
6
7
8
9
10
11
12
//this function is passed the ID of one of the TH elements, and triggers a sort without a click
function trigger_Sort(id) {
	var fakeEvent=new Object;
	fakeEvent.currentTarget=document.getElementById(id).firstChild;
//comment out this block for ascending sort
	for (var i=0; i<fakeevent .currentTarget.childNodes.length; i++) {
		if (fakeEvent.currentTarget.childNodes[i].tagName) {
			fakeEvent.currentTarget.childNodes[i].setAttribute('sortdir','down');
		}
	}
	ts_resortTable(fakeEvent);
}

//this function is passed the ID of one of the TH elements, and triggers a sort without a click function trigger_Sort(id) { var fakeEvent=new Object; fakeEvent.currentTarget=document.getElementById(id).firstChild; //comment out this block for ascending sort for (var i=0; i<fakeevent .currentTarget.childNodes.length; i++) { if (fakeEvent.currentTarget.childNodes[i].tagName) { fakeEvent.currentTarget.childNodes[i].setAttribute('sortdir','down'); } } ts_resortTable(fakeEvent); }