Create your own PBX for VOIP and run it all from within your FreeNAS 11.3 server in a Jail — no WebGUI needed for Asterisk as long as you are comfortable with the command line. I see a lot of folks talking about using FreePBX which looks amazing but honestly I just want to run this in a FreeNAS jail and Asterisk is really all you need. I purchased 11 Cisco 7942 IP Phones for $40 (including FedEXshipping) from Goodwill which is such a deal considering these phones were on sale new until February 2016 for $455.00 USD! Now this phone is a trip to configure for SIP especially if you are going to handcraft the XML which is how we are going to do it (there is plenty of documentation on line to help you). I will draw heavily on an blog article I read from whizzy.org and I will add bits that worked for since I had a slightly different setup. Many thanks to Will Cooke who wrote the article, I’ve literally read it a dozen times and I get a bit more each time I read it. No joke this took me a solid 10 days during Covid-19 lockdown to figure out (obviously not 10 days straight — I set small goals and would keep at it until I got a bit farther…). OK, on to the steps…
Step 1 — Setup FreeNAS Jail
Let’s get a FreeNAS Jail setup and download Asterisk. We won’t configure Asterisk yet, just download and install. We’ll focus on the latest Asterisk version 16. Also, we will want to use SIP for VOIP, Asterisk can do much more but everything is SIP now-a-days.
Step 2 — Setup your Wifi Router for TFTP and NTP
I don’t want to install any specialty software (like a TFTP server or Cisco Call Manager). I have a very capable ASUS router that is flashed with the ever popular Merlin firmware, so I figured I’d enable NTP and TFTP on it. Why does this matter? Well, you see, when a Cisco IP Phone boots it first tries to get an IP4 address via DHCP and next it looks for a local TFTP server to load it’s config. You can specify in the phone the IP address of the TFTP server but by default it’ll look at the same gateway server that it got it’s DHCP address from. ASUS Merlin uses DNSMasq binary for various DNS services and you can enable TFTP within DNSMasq with a few quick steps.
- Flash your router with the latest supported Merlin firmware.
- Login to your routers web GUI, mine is at 192.168.1.1, default login is admin
- In Administration >> System >> Change router password, set the new login name and password. Make sure it’s a strong password.
- In Administration >> System >> Persistent JFFS2 Partition, click Yes on BOTH Format and Enable persistent JFFS
- Before we leave this page, On Basic Config, select Yes to Enable Local NTP Server and Intercept NTP queries. You must then set you Timezone and Daylight Savings parameters.
- Continuing on this page, Find Service and set Enable SSH to “LAN Only”
- Click Apply
- Next, install a FAT32 formatted USB thumb-drive in one of the routers USB slots.
- REBOOT your router. When it comes back up ensure that all the setting you set were applied. NOTE, in Administration >> System >> Persistent JFFS2 Partition >> Format will now be set to “No” and that is correct.
- In an SSH Terminal on your Mac, Windoze or Linux box, connect to your router with ssh <login>@192.168.1.1 use the login and password from the earlier step. You will be prompted to save the server key for your first login, type y or yes.
- In your SSH session, do the following:
cd /jffs/configs vi dnsmasq.conf.add <hit the i key to insert and type> enable-tftp tftp-root=/tmp/mnt/<some directory on that USB thumbdrive>/tftproot <hit esc key to break out of insert mode> <hit SHIFT and ZZ to save>
- While you are still in your SSH session cd to /tmp/mnt and find your USB drive. I set mine to mount as data so I cd’ed to /tmp/mnt/data
- Create the tftproot directory by typing mkdir tftproot
- Set the permissions on that directory to 777 and set the owner to nobody via the chmod and chown commands
- Restart your router again via the web GUI which will end your SSH session.
- When your router is back up check that TFTP service is listening (it’s running on port 69 😉 ) You should see something like this
<user>@<router>:/jffs/configs# netstat -an | grep 69 ... udp 0 0 127.0.0.1:69 0.0.0.0:* udp 0 0 192.168.1.1:69 0.0.0.0:*
Remember this tftproot directory on the USB thumbdrive because you are going to be referencing it a lot. I basically have a terminal window opened and ssh’ed to that directory which I used to create all the XML files to configure the Cisco IP Phones. Remember that every file and subdirectory needs to be chmod’d to 777 and chown’d to nobody so the Cisco phone can read them.
Step 3 — Download the SIP Firmware from Cisco
Remember that I said everything is SIP now-a-days? Well, Cisco used another protocol called Cisco Skinny and I bet 9 times out of 10 any Cisco IP phone that you find used will have the Skinny protocol on it rather than SIP. It’s fairly easy to update the phones. Let’s get the latest software. You do will need to register an account to download the files, it’s free. At the time of writing the latest version is of SIP firmware for the Cisco IP Phone model 7942 is 9.4.2 SR 3 dated 15th February 2017, even though these phones are end-of-life. Bizarre, but good for us. Thanks Cisco! <<< this last comment is from Will Cooke which I thought was funny so I copied it here. You should get the software package labeled “7942 and 7962 SIP IP Phone Firmware Files Only” which is about a 6 Meg zip file. Download it and copy the zip to the tftproot folder and uncompress it. Please remember to set permission on all extracted files to 777 and owner to nobody. BTW, the 7942 and the 7962 are the same phones but the 42 has 2 “lines” and the 62 has 6 “lines”.
Step 4 — Flash the phone with SIP Firmware via the TFTP server
Take your Cisco phone and turn it over. On the back side there is a port labeled 10/100 SW which stands for Switch or the connection to the network switch to be more exact. If you network switch supports PoE (Power over Ethernet) than all you need to do is plug a CAT5 or CAT6 patch cable from the switch to the 10/100 SW labeled port. I have a Cisco Meraki Gb PoE Ethernet switch so I’m all set! If you don’t have a PoE capable switch then you need a power adapter which you can get on Amazon. When you plug in the phone it will attempt to boot and connect to whichever service it was configured for — this won’t work and the phone will spin on registering or it’ll say “Unprovisioned”. What you want to do is flash the firmware that you just downloaded.
- Unplug and then plug the network or power back in and hold down the # key (only takes a few seconds on 7942 model)
- Eventually you will see the “line” lights start to flash orange. When the line lights are flashing type 123456789*0# This will start firmware download mode.
- The screen will go black for a moment and then go through the process of getting an IP address and connecting to the TFTP server Once connected to the TFTP server the software download will start. You can check the server logs on your router to see the connection, the DHCP and finally the TFTP file requests. Note: that it’ll ask for some files that you won’t have and that’s ok for now since we’re focusing on the firmware.
- The upgrade takes 5-10 min normally. The phone will reboot once download is complete and present you with an “Unprovisioned” message on the screen. This is good news! The phone firmware has now been updated — go to the next step, else continue to the next bullet item here.
- If the phone sticks at the “Upgrading screen with the Cisco logo” for more than 10 min with no visible activity then you are in whats called the “Boot Loop”. I had this on about 5 of my phones; I don’t know what causes it but I’ll tell you how to fix it.
- Unplug the phone and replug it again and hold # as it boots (like before) and instead of 1234567890*# do 3491672850*# (notice the pattern of your fingers with each sequence so you can repeat it without even thinking in the future). The “lines” will flash RED this time.
- Do not do anything to the phone until it completely resets and comes back up functional. This essentially formats the flash and only keeps the Cisco Native Unix (CNU). It takes 10+ minutes and for a while it looks like the phone isn’t doing anything (but it is). Be Patient. Your phone will automatically reboot and hopefully this time it’ll connect to the TFTP server and begine the Firmware install.
- You can repeat this process if you ever need to, I did it on my first phone a dozen or more times without any apparent impact to the phone.
Step 5 — Configure the SIP extension in Asterisk
Will Cooke mentioned an important piece of information in mind: The Cisco 7941 can only deal with 8 character passwords, so keep your SIP authentication secret to 8 characters. I haven’t checked if 7942 improves this, YMMV. Ssh to your FreeNAS server and use jexec to ssh into the Asterisk jail. When you are at the command line, do the following:
cd /usr/local/etc/asterisk vi sip.conf <add these lines at the bottom>  deny=0.0.0.0/0.0.0.0 secret=password context=from-internal host=dynamic type=friend nat=no <hit shift ZZ to save it> <then run this command> asterisk -r <at the Asterisk CLI Command Line Interface, type> reload
Step 6 — Create Phone XML Config and Upload to the TFTP Server
As Will Cooke states: Please take the time to read this section fully, this is the part that is most troublesome. The Cisco 7942 is very picky about it’s config file and even a small mistake will stop the phone from working. I spent many days on this step; it will not be uncommon for you to spend many days as well on this. These settings are specific to the 79×[1,2] series of phones running v9.x.x of the SIP firmware. If you are not using this type or hardware or software then these settings are not for you.
Once the phone has loaded it’s firmware and booted, it will go looking for a file called SEP<PHONE MAC ADDRESS>.cnf.xml. So if the MAC address of your phone is 11:22:33:44:55:66 then the config file needs to be named SEP112233445566.cnf.xml. This file needs to be in the root of your TFTP server. The file is CASE SENSITIVE; go back and read that part again. A small typo that thinking a B is an 8 or vice versa will cause hours of “fun” so please check carefully.
Here is my file:
<?xml version="1.0" encodng="iso-8859-1"?> <device> <fullConfig>true</fullConfig> <deviceProtocol>SIP</deviceProtocol> <sshUserId>admin</sshUserId> <sshPassword>cisco</sshPassword> <devicePool> <dateTimeSetting> <dateTemplate>M/D/YA</dateTemplate> <timeZone>Central Standard/Daylight Time</timeZone> <ntps> <ntp> <name>IPADDRESSOFROUTER</name> <ntpMode>Unicast</ntpMode> </ntp> </ntps> </dateTimeSetting> <callManagerGroup> <members> <member priority="0"> <callManager> <ports> <sipPort>5060</sipPort> </ports> <processNodeName>IPADDRESSOFASTERISK</processNodeName> </callManager> </member> </members> </callManagerGroup> </devicePool> <commonProfile> <phonePassword></phonePassword> <backgroundImageAccess>true</backgroundImageAccess> <callLogBlfEnabled>2</callLogBlfEnabled> </commonProfile> <loadInformation>SIP42.9-4-2SR3-1S</loadInformation> <vendorConfig> <settingsAccess>1</settingsAccess> <sshAccess>0</sshAccess> <disableSpeaker>false</disableSpeaker> <disableSpeakerAndHeadset>false</disableSpeakerAndHeadset> <pcPort>0</pcPort> <garp>0</garp> <voiceVlanAccess>0</voiceVlanAccess> <videoCapability>0</videoCapability> <autoSelectLineEnable>0</autoSelectLineEnable> <webAccess>0</webAccess> <daysDisplayNotActive>1,7</daysDisplayNotActive> <displayOnTime>08:00</displayOnTime> <displayOnDuration>10:30</displayOnDuration> <displayIdleTimeout>01:00</displayIdleTimeout> <spanToPCPort>1</spanToPCPort> <loggingDisplay>1</loggingDisplay> <loadServer></loadServer> </vendorConfig> <userLocale> <name>English_United_States</name> <uid>1</uid> <langCode>en_US</langCode> <version>220.127.116.11-1</version> <winCharSet>utf-8</winCharSet> </userLocale> <networkLocale>United_Kingdom</networkLocale> <networkLocaleInfo> <name>United_Kingdom</name> <version>10.5.3.0</version> </networkLocaleInfo> <deviceSecurityMode>1</deviceSecurityMode> <idleTimeout>10</idleTimeout> <authenticationURL></authenticationURL> <directoryURL></directoryURL> <idleURL></idleURL> <informationURL></informationURL> <messagesURL></messagesURL> <proxyServerURL></proxyServerURL> <servicesURL></servicesURL> <transportLayerProtocol>2</transportLayerProtocol> <phonePersonalization>1</phonePersonalization> <autoCallPickupEnable>true</autoCallPickupEnable> <dndCallAlert>1</dndCallAlert> <advertiseG722Codec>2</advertiseG722Codec> <rollover>0</rollover> <joinAcrossLines>0</joinAcrossLines> <capfAuthMode>0</capfAuthMode> <capfList></capfList> <certHash></certHash> <encrConfig>false</encrConfig> <sipProfile> <sipProxies> <backupProxy>IPADDRESSOFASTERISK</backupProxy> <backupProxyPort></backupProxyPort> <emergencyProxy></emergencyProxy> <emergencyProxyPort></emergencyProxyPort> <outboundProxy></outboundProxy> <outboundProxyPort></outboundProxyPort> <registerWithProxy>true</registerWithProxy> </sipProxies> <sipCallFeatures> <cnfJoinEnabled>true</cnfJoinEnabled> <callForwardURI>x--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>true</rfc2543Hold> <callHoldRingback>1</callHoldRingback> <localCfwdEnable>true</localCfwdEnable> <semiAttendedTransfer>true</semiAttendedTransfer> <anonymousCallBlock>0</anonymousCallBlock> <callerIdBlocking>0</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>true</remotePartyID> <userInfo>Phone</userInfo> </sipStack> <autoAnswerTimer>1</autoAnswerTimer> <autoAnswerAltBehavior>false</autoAnswerAltBehavior> <autoAnswerOverride>true</autoAnswerOverride> <transferOnhookEnabled>true</transferOnhookEnabled> <enableVad>false</enableVad> <preferredCodec>none</preferredCodec> <dtmfAvtPayload>101</dtmfAvtPayload> <dtmfDbLevel>3</dtmfDbLevel> <dtmfOutofBand>avt</dtmfOutofBand> <alwaysUsePrimeLine>false</alwaysUsePrimeLine> <alwaysUsePrimeLineVoiceMail>false</alwaysUsePrimeLineVoiceMail> <kpml>0</kpml> <stutterMsgWaiting>0</stutterMsgWaiting> <callStats>true</callStats> <offhookToFirstDigitTimer>15000</offhookToFirstDigitTimer> <silentPeriodBetweenCallWaitingBursts>10</silentPeriodBetweenCallWaitingBursts> <startMediaPort>35900</startMediaPort> <stopMediaPort>65564</stopMediaPort> <phoneLabel>NewPhone</phoneLabel> <natEnabled>false</natEnabled> <natAddress></natAddress> <sipLines> <line button="1" lineIndex="1"> <featureID>9</featureID> <featureLabel>1008</featureLabel> <name>C0255C42118C</name> <displayName>1008</displayName> <contact>1008</contact> <proxy>USECALLMANAGER</proxy> <port>5060</port> <autoAnswer> <autoAnswerEnabled>0</autoAnswerEnabled> <autoAnswerMode>Auto Answer with Headset</autoAnswerMode> </autoAnswer> <callWaiting>1</callWaiting> <authName>SIPNAME</authName> <authPassword>PASSWORD</authPassword> <sharedLine>false</sharedLine> <messageWaitingLampPolicy>3</messageWaitingLampPolicy> <messagesNumber>*97</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>3</featureID> <featureLabel>Hold</featureLabel> </line> </sipLines> <externalNumberMask></externalNumberMask> <voipControlPort>5060</voipControlPort> <dscpForAudio>184</dscpForAudio> <ringSettingBusyStationPolicy>0</ringSettingBusyStationPolicy> <dialTemplate>dialplan.xml</dialTemplate> <softKeyFile>softkeys.xml</softKeyFile> </sipProfile> </device>
Copy this XML file to the root of your TFTP server. You phone will automatically try and load the config; if you are impatient you can hit the settings button on the phone and then hit asterisk key twice then the hash key and finally asterisk key twice ( **#**). This will cause the phone to soft boot and try and load the config. It will probably load the firmware again to finish loading the SIP firmware which is completely natural. If successful after all the reboots, the phone will not show “unprovisioned” and the phone icon next to the “line” button on the right side will NOT have an x in it. Go ahead and make a call!
Need to fill this out.