Fun with Cisco's IP Communicator softphone application

The following is a guide to using the (now EOL) Cisco softphone application “Cisco IP Communicator” version 8.6.6.0 with FreePBX. I know, I know, this is old antique software BUT IT WORKS. The softphone application does not require a unique license key, nor does it call home to Mommy, and nothing in it’s license prohibits you from using it with a non-Cisco PBX. (It’s licensed software so see your Cisco rep. pricing, etc.)

To get this up and running you will need the following:

  1. A copy of the software. You can download it from the usual places on the Internet that hold Cisco software as well as several universities that still use it, along with setup instructions (such as the following URL: Installing Cisco IP Communicator Softphone | ITS Documentation )

  2. IF you want to use the camera on it for video calls, you need to download and install Cisco Unified Video Advantage 2.0 or later software. You will also need to hack your webcam to be recognized by CUVA, instructions for this are located here: CUVA Windows 7 64-bit Support | The Networking Nerd
    and you will also need to modify the SEPMAC config file to turn on video

  3. You will need a running FreePBX17 PBX and some command line familiarity.

  4. You will need a Windows 10 or 11 system.

  5. You will need a USB headset/mic combo that sets up identically with the same name in Device Manager for both Microphone and Speakers. For example I used “Logitech USB Headset” You can hack your existing USB mic/headset to do this if it doesn’t. See Solved: Cisco IP Communicator - No Devices Detected - Cisco Community

Start by installing the IP Communicator softphone let it complete. Right click on the desktop icon for it and select Properties, Compatability and set it to Vista x64, save, you may also need to make an entry in the Windows firewall for it.

Plug in your headset/mix and run the softphone. It should come up. It won’t provision yet. Click the Menu button on the phone and go to Preferences, Network, and click Use These TFTP servers and put in the IP address of the FreePBX system.

On that screen change the Network Adapter to the adapter you normally use, (for example wireless) and note the SEPMAC number down. You will need this to create a TFTP provisioning file. This software uses the odd method of pulling a provisioning file that contains the phone info instead of defining it in the app. You may have to stop and restart the app (right click on the tray icon to do this) to get that preference saved.

On the FreePBX system, install a modified TFTP server (I’ll post instructions for this in a different post) that is modified per: Cisco IP Communicator - #5 by babak.yakhchali - Asterisk Support - Asterisk Community

Create an extension on FreePBX and assign and extension # and password. Don’t exceed 12 characters on the password. A regular chan_pjsip extension will work fine, but if you want BLF keys you will need to install the USECALLMANAGER patch and modify the custom config files and SEPMAC accordingly, just like with a regular Cisco phone.

If you want to use the directory key on the softphone you will need to create a directory.xml file customized for Cisco phones. (I’ll create a separate post for that) Or setup LDAP (you need an LDAP server for that) The directory.xml is limited to 31 entries.

Create a SEPMAC file and dialplan.xml file in your TFTP server folder on your FreePBX system. Here are 2 templates to get you started. Modify accordingly. (actual password have been changed) Note that I use 5160 for chan_sip+callmanger patch you will want to change this to 5060 if using chan_pjsip

root@phony:/tftpboot# cat SEP4C1D968A5331.cnf.xml
<?xml version="1.0" encoding="UTF-8"?>
<device>
    <fullConfig>true</fullConfig>
    <deviceProtocol>SIP</deviceProtocol>
    <ipAddressMode>0</ipAddressMode>
    <sshUserId>cisco</sshUserId>
    <sshPassword>cisco</sshPassword>
    <devicePool>
        <dateTimeSetting>
            <dateTemplate>M/D/YA</dateTemplate>
            <timeZone>Pacific Standard/Daylight Time</timeZone>
                <ntps>
                    <ntp>
                        <name>172.16.1.1</name>
                        <ntpMode>unicast</ntpMode>
                    </ntp>
                </ntps>
        </dateTimeSetting>
        <callManagerGroup>
            <members>
                <member priority="0">
                    <callManager>
                        <name>172.16.1.16</name>
                        <description>FreePBX</description>
                        <ports>
                            <ethernetPhonePort>2000</ethernetPhonePort>
                            <sipPort>5160</sipPort>
                            <securedSipPort>5061</securedSipPort>
                        </ports>
                        <processNodeName>172.16.1.16</processNodeName>
                    </callManager>
                </member>
            </members>
        </callManagerGroup>
        <connectionMonitorDuration>120</connectionMonitorDuration>
    </devicePool>
    <commonProfile>
        <phonePassword>cisco</phonePassword>
        <backgroundImageAccess>true</backgroundImageAccess>
        <callLogBlfEnabled>1</callLogBlfEnabled>
    </commonProfile>
    <loadInformation model="Cisco IP Communicator SoftPhone"></loadInformation>

    <vendorConfig>
        <disableSpeaker>false</disableSpeaker>
        <disableSpeakerAndHeadset>false</disableSpeakerAndHeadset>
        <pcPort>0</pcPort>
        <settingsAccess>1</settingsAccess>
        <garp>0</garp>
        <voiceVlanAccess>0</voiceVlanAccess>
        <g722CodecSupport>2</g722CodecSupport>
        <handsetWidebandEnable>1</handsetWidebandEnable>
        <headsetWidebandEnable>0</headsetWidebandEnable>
        <headsetWidebandUIControl>0</headsetWidebandUIControl>
        <handsetWidebandUIControl>0</handsetWidebandUIControl>
        <videoCapability>0</videoCapability>
        <autoSelectLineEnable>0</autoSelectLineEnable>
        <daysDisplayNotActive></daysDisplayNotActive>
        <displayOnTime></displayOnTime>
        <displayOnDuration></displayOnDuration>
        <displayIdleTimeout>00:05</displayIdleTimeout>
        <webAccess>0</webAccess>
        <spanToPCPort>0</spanToPCPort>
        <loggingDisplay>1</loggingDisplay>
        <displayOnWhenIncomingCall>1</displayOnWhenIncomingCall>
        <loadServer></loadServer>
        <sshAccess>0</sshAccess>
        <sshPort>22</sshPort>
    </vendorConfig>
<phoneServices useHTTPS="false">
    <provisioning>2</provisioning>
    <phoneService type="1" category="0">
      <name>Missed Calls</name>
      <url>Application:Cisco/MissedCalls</url>
      <vendor></vendor>
      <version></version>
    </phoneService>
    <phoneService type="1" category="0">
      <name>Received Calls</name>
      <url>Application:Cisco/ReceivedCalls</url>
      <vendor></vendor>
      <version></version>
    </phoneService>
    <phoneService type="1" category="0">
      <name>Placed Calls</name>
      <url>Application:Cisco/PlacedCalls</url>
      <vendor></vendor>
      <version></version>
    </phoneService>
    <phoneService type="2" category="0">
      <name>Voicemail</name>
      <url>Application:Cisco/Voicemail</url>
      <vendor></vendor>
      <version></version>
    </phoneService>
    <phoneService type="1" category="0">
      <name>Contacts</name>
      <url>http://phony.pdnit.com/cisco/directory.xml</url>
      <vendor></vendor>
      <version></version>
    </phoneService>
  </phoneServices>
    <userLocale>
        <name>English_United_States</name>
        <uid>1</uid>
        <langCode>en_US</langCode>
        <version>1.0.0.0-1</version>
        <winCharSet>utf-8</winCharSet>
    </userLocale>
    <networkLocale>United_States</networkLocale>
    <networkLocaleInfo>
        <name>United_States</name>
        <version>1.0.0.0-1</version>
    </networkLocaleInfo>
    <deviceSecurityMode>1</deviceSecurityMode>
    <authenticationURL></authenticationURL>
    <directory></directory>
    <idleTimeout>0</idleTimeout>
    <idleURL></idleURL>
    <informationURL></informationURL>
    <messagesURL></messagesURL>
    <proxyServerURL></proxyServerURL>
    <servicesURL></servicesURL>
    <dscpForSCCPPhoneConfig>96</dscpForSCCPPhoneConfig>
    <dscpForSCCPPhoneServices>0</dscpForSCCPPhoneServices>
    <dscpForCm2Dvce>96</dscpForCm2Dvce>
    <transportLayerProtocol>1</transportLayerProtocol>
    <dndCallAlert>5</dndCallAlert>
    <capfAuthMode>0</capfAuthMode>
    <capfList>
        <capf>
            <phonePort>3804</phonePort>
        </capf>
    </capfList>
    <certHash></certHash>
    <encrConfig>false</encrConfig>
    <sipProfile>
        <sipProxies>
            <backupProxy></backupProxy>
            <backupProxyPort></backupProxyPort>
            <emergencyProxy></emergencyProxy>
            <emergencyProxyPort></emergencyProxyPort>
            <outboundProxy></outboundProxy>
            <outboundProxyPort></outboundProxyPort>
            <registerWithProxy>true</registerWithProxy>
        </sipProxies>
        <sipCallFeatures>
            <cnfJoinEnabled>true</cnfJoinEnabled>
            <callForwardURI>x-cisco-serviceuri-cfwdall</callForwardURI>
            <callPickupURI>x-cisco-serviceuri-pickup</callPickupURI>
            <callPickupListURI>x-cisco-serviceuri-opickup</callPickupListURI>
            <callPickupGroupURI>x-cisco-serviceuri-gpickup</callPickupGroupURI>
            <meetMeServiceURI>x-cisco-serviceuri-meetme</meetMeServiceURI>
            <abbreviatedDialURI>x-cisco-serviceuri-abbrdial</abbreviatedDialURI>
            <rfc2543Hold>false</rfc2543Hold>
            <callHoldRingback>2</callHoldRingback>
            <localCfwdEnable>true</localCfwdEnable>
            <semiAttendedTransfer>true</semiAttendedTransfer>
            <anonymousCallBlock>2</anonymousCallBlock>
            <callerIdBlocking>2</callerIdBlocking>
            <dndControl>0</dndControl>
            <remoteCcEnable>true</remoteCcEnable>
        </sipCallFeatures>
        <sipStack>
            <sipInviteRetx>6</sipInviteRetx>
            <sipRetx>10</sipRetx>
            <timerInviteExpires>180</timerInviteExpires>
            <timerRegisterExpires>3600</timerRegisterExpires>
            <timerRegisterDelta>5</timerRegisterDelta>
            <timerKeepAliveExpires>120</timerKeepAliveExpires>
            <timerSubscribeExpires>120</timerSubscribeExpires>
            <timerSubscribeDelta>5</timerSubscribeDelta>
            <timerT1>500</timerT1>
            <timerT2>4000</timerT2>
            <maxRedirects>70</maxRedirects>
            <remotePartyID>false</remotePartyID>
            <userInfo>None</userInfo>
        </sipStack>
        <autoAnswerTimer>0</autoAnswerTimer>
        <autoAnswerAltBehavior>false</autoAnswerAltBehavior>
        <autoAnswerOverride>true</autoAnswerOverride>
        <transferOnhookEnabled>true</transferOnhookEnabled>
        <enableVad>false</enableVad>
        <preferredCodec>g711ulaw</preferredCodec>
        <dtmfAvtPayload>101</dtmfAvtPayload>
        <dtmfDbLevel>3</dtmfDbLevel>
        <dtmfOutofBand>avt</dtmfOutofBand>
        <alwaysUsePrimeLine>false</alwaysUsePrimeLine>
        <alwaysUsePrimeLineVoiceMail>false</alwaysUsePrimeLineVoiceMail>
        <kpml>3</kpml>
        <stutterMsgWaiting>0</stutterMsgWaiting>
        <callStats>false</callStats>
        <silentPeriodBetweenCallWaitingBursts>10</silentPeriodBetweenCallWaitingBursts>
        <disableLocalSpeedDialConfig>false</disableLocalSpeedDialConfig>
        <startMediaPort>16384</startMediaPort>
        <stopMediaPort>32766</stopMediaPort>
        <voipControlPort>5160</voipControlPort>
        <dscpForAudio>184</dscpForAudio>
        <ringSettingBusyStationPolicy>0</ringSettingBusyStationPolicy>
        <dialTemplate>dialplan.xml</dialTemplate>
        <softKeyFile>softkeys.xml</softKeyFile>
        <phoneLabel>809</phoneLabel>
        <natEnabled>true</natEnabled>
        <natAddress></natAddress>

        <sipLines>
            <line button="1">
                <featureID>9</featureID>
                <featureLabel>809 TedsLap</featureLabel>
                <name>809</name>
                <displayName>809</displayName>
                <contact>809</contact>
                <proxy>USECALLMANAGER</proxy>
                <port>5160</port>
                <autoAnswer>
                    <autoAnswerEnabled>0</autoAnswerEnabled>
                </autoAnswer>
                <callWaiting>1</callWaiting>
                <authName>809</authName>
                <authPassword>64BADBEEF13</authPassword>
                <sharedLine>false</sharedLine>
                <messageWaitingLampPolicy>3</messageWaitingLampPolicy>
                <messagesNumber>*98</messagesNumber>
                <ringSettingIdle>4</ringSettingIdle>
                <ringSettingActive>5</ringSettingActive>
                <forwardCallInfoDisplay>
                    <callerName>true</callerName>
                    <callerNumber>false</callerNumber>
                    <redirectedNumber>false</redirectedNumber>
                    <dialedNumber>true</dialedNumber>
                </forwardCallInfoDisplay>
            </line>

      <line button="2">
        <featureID>4</featureID>
        <featureLabel>Transfer</featureLabel>
      </line>


            </sipLines>
    </sipProfile>

</device>
root@phony:/tftpboot#

Here’s the dialplan:

root@phony:/tftpboot# cat dialplan.xml
<DIALTEMPLATE>
        <TEMPLATE MATCH="8.."   Timeout="0"     User="Phone"/><!-- Internal extensions 800 to 899. Dial immediately. -->
        <TEMPLATE MATCH="\*97"  Timeout="0"/><!-- *97 for voicemail. Dial immediately. -->
        <TEMPLATE MATCH="\*98"  Timeout="0"/><!-- *97 for voicemail. Dial immediately. -->
        <TEMPLATE MATCH="*#"    Timeout="0"     REWRITE="%1"/><!-- Dial immediately after pressing #. Do not send the # sign. -->
        <TEMPLATE MATCH="503......."    Route="Default" Timeout="0"     User="Phone"/> <!-- Dial immediately after a local call -->
        <TEMPLATE MATCH="*"     Timeout="5"/> <!-- Anything else, wait 5 seconds then dial. -->
</DIALTEMPLATE>
root@phony:/tftpboot#

Have phun with it!! :wink:

As I mentioned for this to work you need to make a trivial modification to the TFTP server. As far as I know this is the ONLY phone or phone software that requires this. Even the Cisco deskphones do not need this tftpd server modification. Cisco must have hacked up whatever tftp server they are using on their UCM specifically for this software. Who knows why - maybe they knew the softphone software would work with competitive PBXes and wanted to just stick it to anyone trying this out with a competitive PBX. But of course all that’s ancient history and the situation with this is similar to many older highly useful Cisco utilities (Windows IPSecVPN client, Windows tftp server, etc.) which were released and then when Cisco later realized they could charge extra money for more licensing for different programs they withdrew them (the situation with the Cisco IPSec client is particularly egregious but I digress)

On Debian 12 the tftp server is tftpd-hpa. You may not even have it installed on your FreePBX system. By default FreePBX 17 systems setup /tftpboot with Sangoma’s telephone firmware.

Here’s the instructions:

cd /root
su

Check to see that the sources line is present that is detailed here:

https://wiki.debian.org/BuildingTutorial

I'll use part of this tutorial and skip the part about packaging the modified tftpd server.

apt-get update

Delete the system tftpd service

apt-get remove tftpd-hpa
apt-get purge tftpd-hpa

Note that this will wipe the tftp-hpa config file so if you have made changes then save them.  It won't mess with the /tftpboot directory (or shouldn't but I'd make a backup of course if you have phone firmware in there you are using)

Install the Debian package tools:

apt-get install build-essential fakeroot devscripts

Now setup the build area, download and build the Debian source for tftpd-hpa

mkdir -p src/debian/; cd src/Debian
apt-get source tftp-hpa
apt build-dep tftp-hpa
cd tftp-hpa-5.2+20150808
debuild -b -uc -us

Note that the version of tftpd-hpa may have increased beyond 5.2+20150808 so adjust accordingly.

This should complete successfully.  Now install it:

root@phony:~/src/debian/tftp-hpa-5.2+20150808# apt install ../tftpd-hpa_5.2+20150808-1.4_amd64.deb
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Note, selecting 'tftpd-hpa' instead of '../tftpd-hpa_5.2+20150808-1.4_amd64.deb'
Suggested packages:
  pxelinux
The following NEW packages will be installed:
  tftpd-hpa
0 upgraded, 1 newly installed, 0 to remove and 219 not upgraded.
Need to get 0 B/41.9 kB of archives.
After this operation, 117 kB of additional disk space will be used.
Get:1 /root/src/debian/tftpd-hpa_5.2+20150808-1.4_amd64.deb tftpd-hpa amd64 5.2+20150808-1.4 [41.9 kB]
Preconfiguring packages ...
Selecting previously unselected package tftpd-hpa.
(Reading database ... 284492 files and directories currently installed.)
Preparing to unpack .../tftpd-hpa_5.2+20150808-1.4_amd64.deb ...
Unpacking tftpd-hpa (5.2+20150808-1.4) ...
Setting up tftpd-hpa (5.2+20150808-1.4) ...
tftpd user (tftp) already exists, doing nothing.
Processing triggers for man-db (2.11.2-2) ...
N: Download is performed unsandboxed as root as file '/root/src/debian/tftpd-hpa_5.2+20150808-1.4_amd64.deb' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)
root@phony:~/src/debian/tftp-hpa-5.2+20150808#

This installs

/usr/sbin/in.tftpd

which is the binary along with all the config files.  Now we are going to patch it:

Make sure the maker completes properly:

root@phony:~/src/debian/tftp-hpa-5.2+20150808# make
make -C  
make[1]: Entering directory '/root/src/debian/tftp-hpa-5.2+20150808/lib'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/root/src/debian/tftp-hpa-5.2+20150808/lib'
make -C  common
make[1]: Entering directory '/root/src/debian/tftp-hpa-5.2+20150808/common'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/root/src/debian/tftp-hpa-5.2+20150808/common'
make -C  tftp
make[1]: Entering directory '/root/src/debian/tftp-hpa-5.2+20150808/tftp'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/root/src/debian/tftp-hpa-5.2+20150808/tftp'
make -C  tftpd
make[1]: Entering directory '/root/src/debian/tftp-hpa-5.2+20150808/tftpd'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/root/src/debian/tftp-hpa-5.2+20150808/tftpd'
root@phony:~/src/debian/tftp-hpa-5.2+20150808#

Now apply the patch:

cd tftpd
cp tftpd.c  tftpd.c.orig

Insert patch listed in this URL:

https://community.asterisk.org/t/cisco-ip-communicator/46041/2

Here's an actual diff of the patch if you have any concern where it goes.  Note newer versions of tftp-hpa may change the line numbers where this goes:

root@phony:~/src/debian/tftp-hpa-5.2+20150808/tftpd#  diff -u tftpd.c.orig tftpd.c
--- tftpd.c.orig        2024-11-16 09:37:52.572659519 -0800
+++ tftpd.c     2024-11-16 11:41:29.406100168 -0800
@@ -1096,6 +1096,11 @@
         }

         argn++;
+
+        /* begin Tad’s playing with the stupid zero that Cisco’s tfpd ignores */
+        if ( *(cp+1) == 0) { ++cp;}
+        /* end Tad’s playing with the stupid zero that Cisco’s tfpd ignores */
+
         if (argn == 1) {
             mode = ++cp;
         } else if (argn == 2) {
root@phony:~/src/debian/tftp-hpa-5.2+20150808/tftpd#

cd ..

make

Note the output will be as above except it will recompile tftpd.

Ignore the longjump warning it is present in the original Debian build apparently the maintainers don't see it as a problem

Now we make a backup of the working tftpd and put our modified version there.

root@phony:~/src/debian/tftp-hpa-5.2+20150808/tftpd# mv /usr/sbin/in.tftpd /usr/sbin/in.tftpd.bak
root@phony:~/src/debian/tftp-hpa-5.2+20150808/tftpd# mv tftpd /usr/sbin/in.tftpd

change /etc/default/tftpd-hpa file to

TFTP_USERNAME="tftp"
# TFTP_DIRECTORY="/srv/tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure -vvv"

The extra v's will put the files transferred into the /var/log/syslog file which is useful for trobleshooting.

systemctl restart tftpd-hpa

Check that it works under a Windows machine

Open windows command line
turn off Windows Firewall
issue command:

C:\Users\tedm\Downloads>tftp -i phony.pdnit.com get sangoma/0/fw100.rom
Transfer successful: 5893150 bytes in 24 second(s), 245547 bytes/s

C:\Users\tedm\Downloads>

Now put your SEPMAC and dialplan.xml files in /tftpboot and fire up IP Communicator and check the log to see that it transfers it's config files properly.

Edit:

should be

mkdir -p src/debian/; cd src/debian

Also, just a FYI for Debian 12 the sources additional lines would be:

deb http://deb.debian.org/debian/ bookworm main non-free-firmware
deb-src http://deb.debian.org/debian/ bookworm main non-free-firmware

deb http://security.debian.org/debian-security bookworm-security main non-free-firmware
deb-src http://security.debian.org/debian-security bookworm-security main non-free-firmware

For Ubuntu 22.04 Desktop the sources lines would be:

deb-src http://archive.ubuntu.com/ubuntu jammy main restricted #Added by software-properties
deb-src http://gb.archive.ubuntu.com/ubuntu/ jammy restricted main universe multiverse #Added by software-properties
deb-src http://gb.archive.ubuntu.com/ubuntu/ jammy-updates restricted main universe multiverse #Added by software-properties
deb-src http://gb.archive.ubuntu.com/ubuntu/ jammy-backports main restricted universe multiverse #Added by software-properties
deb-src http://security.ubuntu.com/ubuntu jammy-security restricted main universe multiverse #Added by software-properties
deb-src http://gb.archive.ubuntu.com/ubuntu/ jammy-proposed restricted main universe multiverse #Added by software-properties

One final thing about the Cisco IP Communicator softphone application. It seems to have a lot of problems registering over a VPN. I’m investigating this but have no answer as to why, at the moment. Registration over a routed network seems to be fine.

Ted