Cisco Tips

Cisco CME Tips

Voicemail integration with Microsoft Exchange

I don't know if it's a peculiarity of the SIP provider, but I found that a no-answer voicemail redirect would fail to transfer calls from the POTS to Exchange if the timeout was set to 20 or more seconds. It was still hitting Exchange and generating 'missed call' emails, though. Crank down the time and answer the phone quicker, slacker.

Cisco Unity Express voicemail

Voicemail in general takes a bit of planning to do 'right' with CUE. At the installation I took over, everyone had been set up with a mailbox and call forward busy 8000 diversions, where 8000 was the general number for everyone.

A much more flexible method is to make a new dial-peer with a voicemail prefix so that everyone gets a voicemail number (eg 8xxxx, where xxxx is the extension). You'll also need to set everyone's E164 number to the voicemail one. This means you can do tricky things like redirecting calls to specific mailboxes. If you have group mailboxes, this is much better than doing silly hacks like forwarding to an ephone-dn with the group mailbox's number and a call forward all, which I couldn't get working properly at all - I had to set call forward noan instead.

One issue with doing this was that people had to start entering their extension when logging in to the mailbox, and those who'd been too lazy to set up voice mail no longer could. This was because the FNN was being sent to CUE (0882xxxxxx) rather than the extension. Oh, the FNN must have originally been in CUE before I started messing with it. The solution was to set up a simple translation rule that stripped the leading numbers.

Another issue - you can't set the E164 number for group mailboxes through the Web interface. Dive in on the console using the special CUE incantation and set it manually.

Code to come when I can be bothered.

SIP Softphone Integration

Attaching Cisco IP phones that use SCCP is relatively easy. Getting a third-party SIP softphone to work was much harder!

 voice service voip 
  allow-connections h323 to h323
  allow-connections h323 to sip
  allow-connections sip to h323
  allow-connections sip to sip
  supplementary-service h450.12
   registrar server expires max 1200 min 300

 voice class codec 1
  codec preference 1 g729r8
  codec preference 2 g711ulaw

Some guides suggested using g711ulaw first, but I already had g729r8 on there. I didn't want to fiddle too much and break the existing phone system.

 voice register global
  mode cme 
  source-address port 5060
  max-dn 192
  max-pool 110
  authenticate register
  file text
  create profile
 voice register dn  69
  number 9095
  name 9095
  label Joeltest
 voice register pool  69
  id mac xxxx.xxxx.xxxx
  number 1 dn 69
  voice-class codec 1
  username 9095 password 9095

I got it working with the free Zopier SIP client, which I intended to use as a temporary fax gateway but couldn't. I tried using Brooktrout's VoIP fax modem thingy, which didn't seem to work well either, and ended up using T.37 fax-to-email offramp on the CME instead. Why pay good money for fax-to-email when you've already bought a freakin' expensive PABX that can do it? The only problem is that I have no idea how you're meant to use T.37 to send outgoing faxes. Is there a printer driver that makes TIFFs and uploads them? Until that I'm stuck using an email-to-fax gateway with an analogue modem, which fails whenever someone kicks it onto the floor.

In Zoiper, add a SIP account. Domain is the IP of the CME ( here), username and password are 9095, auth. username are 9095. The important thing seems to be to use a number for the username. I couldn't get it working with a word and this took me ages to figure out (!). Didn't bother with SIP proxy, though it seemed to work with it.

All this got me going with outgoing calls, but not incoming (through an E1). My somewhat scummy workaround was to create an ephone-dn for the desired incoming number and call-forward all to the SIP phone's extension. On the other hand, I tried it again on a UC520 and it worked both ways, though I did have to explicitly set the codec in my voice register pool. Haven't confirmed this as I've had no reason to give SIP clients direct in-dial numbers since.

I'm not entirely sure it doesn't break incoming calls coming in to our phone system, either. Will update once I figure it out! I suspect that if you trunk to a SIP provider for some other reason (eg, it's your upstream phone provider), fiddling around with voice register global can break it. Either that or CME is very touchy and needs to be rebooted while fiddling with these things. I've decided that resetting the SIP connection completely screws things up. Last time I did this it broke outgoing calls but not incoming until I rebooted. I've since discovered that it's better to just re-register phone numbers with the SIP provider, which can be done by changing the ephone-dn's number (at least the one that has a 'reg') to something else and back again.

SIP building public address system

The PABX being replaced had an intercom function where you could dial some number and make announcements over a PA system. So that we didn't look silly for selling the customer a phone system worse than their old one, I decided to hack up a SIP client that auto-answered and sent audio out the sound card, which could be plugged in to the PA amplifier. I wanted something that ran as a service or daemon and didn't have a fancy GUI, as it needed to be installed on a Windows server that wasn't necessarily logged in. I don't know what's up with soft phone and audio player software authors creating stupid graphical interfaces, but after some searching I discovered PJSIP, a SIP library with some good example programs.

Here's a command line example for registering pjsua with CME and the above username and password:

 ./pjsua-i386-apple-darwin9.5.0 --username 9095 --password 9095
   --id=sip:9095@ --registrar=sip:
   --realm="*" --auto-answer=200

I eventually managed to do this by hacking the pjsua_simple example code to auto-answer, hard-code all configuration, and run as a Windows service. I bought a cheap USB sound card on eBay as the HP DL server didn't have one. It worked very well, except that the server I chose was the same one that the organisation's footy tipping software ran on. I was very careful to disable all of the Windows system sounds, but this particular program blasted out a full-time siren throughout the building whenever it was started. Predictably, the PA system had speakers in every part of the building other than the server room so this wasn't discovered until someone poked their head in and asked what was going on.

VIC2-2FXS Card

I installed one of these two port FXS cards and was disappointed to find that only one of the ports worked - one gave a dial tone and could be used to place calls, while the other was dead and/or just made the two in-use lights come on when a handset was plugged in. I raised an RMA and ordered a second card.. which had exactly the same problem. After three hours on the phone to Cisco's TAC, we determined that the phone cable being used to hook up the fax machine I was trying to get working had a reversed centre pair. When replaced with a straight through cable, the second port worked normally.

Even more bizarre was that the handset I was testing with, an old Telstra Touchphone, was being used with a normal straight cable. Once I replaced that with the reversed cable, both ports worked fine!

This leads me to believe that the VIC2-2FXS has its ports wired up the wrong way or has some hardware bug that no-one has ever noticed before for some unknown reason, or that the universe is truly an awful place. I now carry both straight and reversed cables and fiddle around until I find a combination that work. This was a much easier solution that learning how analogue telephone lines work!

Forward a bunch of overlay lines

Night service mode works well for forwarding a whole bunch of calls, but it's not easy to manually divert (eg using CFwdAll on a handset) a number of lines that are overlaid on one button. I came across this when someone wanted to be able to divert a customer service line to a "we're all in a meeting" mailbox that had a message different to the "we've all gone home" night message. I investigated using SNMP to set call forwarding (never really understood why SNMP was so hard. Could only find read-only MIB for call forwarding) and writing a TAPI client (poor documentation, way too complex, didn't want to have to support a desktop app) before I created the Devil's own ASP page, which simply telnetted in to the router, issued a conf t and began adding or removing call-forward all lines to the ephone-dn sections.

A better solution seems to be to use the auto-attendant to route things intelligently, though I'm not sure if it's easy to arbitrarily reconfigure it at will. On the other hand, it seems much less scummy to have a telnet script that changes AA parameters than ephone-dn parameters.

I did find a nasty IOS bug that, after turning call-forward all on and off for the overlay lines and turning night service mode on and off, would randomly start call forwarding on those lines again. It took my bleedin' ages to get Cisco TAC to understand what was happening, but happily they were able to replicate it and issue a fix several months later. If you notice anything of the sort, upgrade!

Write XML applications for 79xx phones

XML applications are fraught with frustration. Here are a few things I've found.

  • The undocumented <CiscoIPPhoneError Number="0" /> error appears when you attempt to push execute commands to the phone. The phone's logs show things like JVM: extractHostFromUrl() invalid hostname, url:<?UserID=foo&Password=bar&devicename=SEP... This means that you've not set an url authentication under your telephony service and/or haven't reset the phone since changing it, since this URL is only retrieved when the phone resets.
  • You've pointed the authentication URL somewhere and now you get <CiscoIPPhoneError Number="4" />. I tried a few things before coming up with the following allow-all script. The phones are really picky about message formats and headers, so a plain text file just wouldn't work. If you're using voiceview, you'll need to think a bit harder before doing this.
print "Content-type: text/plain\n\n";
  • When you view the phone's logs using wget or curl or by refreshing the log page, it never updates. This is because it is the process of looking at the list of logs that causes them to actually be updated. Either curl the list of logs and redirect it to null first, or just give in and use the Web page normally.
  • Broadcasting to all phones. Useful, for example, if you wish to have an office-wide public address broadcast. Unfortunately there is no easy way to do this other than by generating a list of addresses and connecting to them all, hopefully at about the same time, enabling multicast audio streaming, performing the broadcast, and then turning the stream off. I did this using a multi-threaded ASP.NET page. It worked quite well, but felt dirty. It's fun pressing a button and hearing speakerphone beeps emanating from all of the phones in a building in quick succession. There was really no point in doing this because you can use a paging dn. I just hadn't known that they existed at the time.
  • I hooked up my work's phones to a ZoneMinder instance with a few custom scripts, making it possible to view security cameras through a simple menu. This was pretty simple - ZoneMinder has a CGI script that outputs a JPEG image. I wrote another CGI script that loads the JPEG image via HTTP, then converts it to PNG using the GD library. Less scummy would have been to examine the ZoneMinder script and add the format conversion in there, but I knocked most of this up while having Friday afternoon beers. Then there was just a simple menu that selected the four cameras.
  • The next step was to assign a soft button on the phone that called another CGI script that operated a relay that released the latch on the office's front door. This meant that you could see who was at the door on the screen and 'buzz' them in. I also planned to hook this up with pjsip so that when someone pressed the doorbell, the doorbell would call the main office number. Whoever answered would have the door image pushed to their phone, and then have the ability to chat to them and optionally let them in. I ran out of time to do this but found a few problems:
    • The serial port relay circuit I made kept getting locked on, and thus the door would be left unlocked. I think this was a software resource locking issue.
    • The intercom was really quiet and I couldn't see any obvious way to improve this as it's a two-wire system that I didn't care to reverse engineer. Hooking it up to the sound card would have been pretty straightforward, but I never got around to it.

Reset CUE voice mail password

Log in to service module. Here's a handy tip: from IOS, do:

conf t
alias exec cue service-module integrated-service-engine 0/0 session

Now from the normal prompt you can enter cue to get to the CUE console.

To reset password

username UserName pin 1234

Writing auto-attendant scripts

I had to write an auto-attendant script to do some special call handling (to replace the thing with redirecting overlay lines described earlier, which broke nastily after an IOS upgrade). Instead of manually redirecting calls, I use night mode and a system schedule to choose where to redirect calls. Anyway, the editor was a bit weird to use and very, very poorly documented. Here are a few things I picked up.

  • You need to have an Accept (contact: --Triggering Contact--) line right after Start, or else you'll get a system problem message.
  • To use Business Hours, define a parameter for the schedule. You can then select the schedule when configuring the auto-attendant through the CUE Web GUI.
  • You can redirect calls to an extension by using a number. The documentation mentions a bunch of other special values, but not this. It's obvious, but I was stumped by the problem with a missing Accept line so I thought I was doing something wrong with redirections.

Connect to CME with PJSIP

I couldn't get it to work until I set a realm on the CME:

voice register global
  authenticate realm foo

It didn't matter what it was set to, but clearly needed something. In pjsua I just specified --realm='*'.

DSP and transcoding

I've done this several times and always forget how to do it. The scenario - you are stingy and have a SIP provider rather than ISDN lines, and you're using Unity Express or Exchange's voicemail system or something. You have set up voicemail properly and it works internally, but from outside calls are dropped or get an error when they're transferred to voicemail. You have a codec mismatch! The solution:

voice class codec 1
 codec preference 1 g711alaw
 codec preference 2 g729r8

I don't think this is strictly necessary but it doesn't hurt, and I'm not removing it now to see what happens. Specify the codecs that your SIP provider and voicemail system use.

voice-card 0
 dsp services dspfarm

sccp local Loopback0
sccp ccm identifier 1 version 4.1 

sccp ccm group 1
 bind interface Loopback0
 associate ccm 1 priority 1
 associate profile 1 register HWCONF
 switchover method immediate
 switchback method immediate
 switchback interval 60 happens to be the IP address of the phone VLAN (in a default UC500 setup).

Some guides say that the tag needs to be of the form mtpxxxxxxxxxxxx , embedding the MAC address of the interface, but this doesn't actually seem to matter - at least not when you're doing call processing and DSP on the same box. I've never tried doing it on a separate router.

dspfarm profile 1 transcode  
 codec g711ulaw
 codec g711alaw
 codec g729r8
 codec g723r63
 codec g723r53
 codec g729ar8
 codec g729br8
 codec g729abr8
 maximum sessions 7
 associate application SCCP

I don't see why you wouldn't just put all of the codecs here in case. There are a couple more that I left out while troubleshooting, but my systems didn't use them so it didn't matter. It's handy to have them all there in case your SIP provider decides to change codecs without warning.

 sdspfarm units 4
 sdspfarm transcode sessions 10
 sdspfarm tag 1 HWCONF

Note, all of these numbers are pretty arbitrary. The transcode sessions line here is mandatory - it will not do any transcoding without it.

7291G and other wireless IP phones

Scenario: nobody uses CME, but you've sold one to a customer and they're still on back-order when they move into their new office. You've found a UC520 at the tip, but the WiFi antenna is missing. You plug a non-Cisco access point into one of the switch ports, which works fine for computers but the 7921G phone will not associate or even detect any wireless networks in the site survey. You've tried setting the access point to B/G only, removing encryption, and setting the channel to 1.

Solution: It turns out that it's necessary to have world-mode set on the access point before the phones will even consider joining. I didn't research what this means or why, but put world-mode dot11d country AU both in your radio interface. Obviously the non-Cisco access point will not support this command (though maybe it has a comparable world mode setting somewhere that will work?) so you'll have to keep rummaging through bins to find the antenna or an Aironet AP.

Cisco ASA Tips


Contrary to every other Cisco product, pre-shared keys do not show up in a show running-configuration. They're replaced by * instead. Don't take this to mean "use the globally defined key" or something silly like that - if you clag * in as the key, your key really will be *. It's probably better to copy the config around using tftp, as this preserves keys. Alternatively, you can view the actual running-config with more system:/running-config.

Password recovery

I ran in to a nasty issue where performing a password recovery on an ASA 5510 caused the PPPoE password to be lost. I'm not /entirely/ sure if that's what happened, because show run doesn't give the encrypted passwords, but resetting the password with the ISP and putting the new one in certainly helped. It's a good idea to have all your keys and details stored somewhere safe! Copying the config off with tftp or getting in to the habit of using more system:/running-config preserves keys and passwords. The command line is a lot less nice on the ASA than IOS routers - what's up with that?

Recovering pre-shared keys and PPPoE passwords

On an ASA or a PIX 7 you can do more system:running-config .

On a PIX 6 you have to copy the config to a TFTP server, or even easier, enable the HTTP server and go to https://ip.address/config .


I upgraded an ASA 5510 from 7.2(3) to 8.0(3), or possibly something similar, and no config changes were required! Everything kept on working. My advice: approach such upgrades with reckless abandon. Upgrading a 2851 running CME was a different story - this seemed to break SIP (though contrary to the revelations obtained in earlier paragraphs, I ended up not using it anyway). This appears to be because CME is only integrated into certain IOS versions. It's better to stay within the same release track (eg XW) if you're doing voice things rather than going for the shiny new T series release, which are really just for generic routers, maybe. Your life is difficult enough already - why are you needlessly upgrading the IOS?

Changing NAT exclusion rules does nothing

When changing NAT exclusion rules, I found that nothing seemed to be working. I ignored errors that said "Unable to download NAT policy for ACE", but it turns out that these are what stopped it from working. The solution was to either reboot or do a no nat (inside) 0 access-list foo-acl and a nat (inside) 0 access-list foo-acl. This was in the 8.0(3) release and may have been fixed in later interims. Wasted lots of my time.

IPSec LAN to LAN problems

A customer connected to an ASA 5510 via IPSec had their IP address change when they moved. No problem, just add a new tunnel group and change the crypto map peer address. This didn't work, and I got messages like PHASE 1 COMPLETED, All IPSec SA proposals found unacceptable. Everything looked fine in the config - it was working beforehand, after all!

In the end I fixed it by blowing away the crypto map entry on the ASA and making a new one *with a new sequence number*. For some reason there was a bit of the old one hanging around. I suspect this might be related to the bug where I can't delete certain bits of config, such as lines of the form "crypto map Outside_map 20 set security-association lifetime seconds 28800". It's possible it'll be fixed after a reboot. I can only hope!

I tried to do LAN to LAN from a PIX 506E to an ASA 5505 and couldn't get it to work at all due to a phase 2 failure until I disabled pfs.

Cisco 1130AG Tips

It turns out that there's something magical about bridge group 1 on the 1130AG. I configured one on a network that had VLANs (data and voice) and wanted AP management to be on the data VLAN. VLAN subinterfaces can't be in the same bridge group as physical interfaces (and can't have bridge 10 route ip set). The result of all this is that while you can set an IP address on a BVI associated with a non-native VLAN, it's not accessible from anywhere. If you put the IPs on the associated subinterfaces, it's accessible from that side of the network but IP routing doesn't work! This exhibited itself as a ping to a remote host generating continuous ARP requests for the default router, even though it was in the ARP table. I presume some VLAN tagging oddity might have been at play here.

Anyway, the point is that I fixed it by moving the physical interfaces to a different bridge group and putting the 'management' subinterfaces on 1. After doing this, BVI1 and routing worked as expected.

See also

Cisco7xxReset - How to reset the configuration of a 700 series Cisco router.