VoIP – James Batchelor https://james-batchelor.com Useful I.T & VoIP Ramblings Sat, 19 Jul 2025 19:01:32 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.5 https://james-batchelor.com/wp-content/uploads/2025/05/cropped-cropped-logo-jb-202505-32x32.png VoIP – James Batchelor https://james-batchelor.com 32 32 SIP Radio https://james-batchelor.com/index.php/2025/09/17/sip-radio/ Wed, 17 Sep 2025 19:00:00 +0000 https://james-batchelor.com/?p=1044 Continue reading "SIP Radio"]]> In a previous post, I hinted at the possibility of replacing a “smart” speaker with readily placed VoIP phones as a way to play radio around the house.

This would kind of make sense, phones use the RTP protocol for audio is designed for real-time communication and so, naturally sync with each other in a local network.

As a proof of concept, I wanted to create a service that allowed me to “dial-in” to a radio stream on demand…

Initial thoughts was to just to pipe a continuous radio stream to an extension. However, in addition to the waste of bandwidth, any network disruptions would essentially kill the stream without recovery. Therefore, a play on-demand service would help keep the stream fresh whilst saving bandwidth at idle.

My preferred radio for testing is Kerrang radio, I get the URL’s for radio feed via this site and downloading the playlist .pls file, then opening the file in a text editor to extract the actual stream URL.

Baresip Setup

Similar to the earlier project in piping audio from a Raspberry Pi to SIP, a minimal install of Baresip will be used to handle the SIP element and added as a system service in a mostly similar way.

To give the script some context on when to play on demand, we need a log of baresip’s output.

In the service configuration file, under [service] change the following line:

ExecStart=/usr/bin/baresip

to:

ExecStart=/bin/bash -c "/usr/bin/baresip > /path/to/sipaudio.log 2>&1"

This will now run the application and send all output to a sipaudio.log file for processing by the script.

Script

The script will read the log file for any newly established calls and add them to a counter to establish how many calls are active, while the call count is greater than zero, trigger the radio stream.

Similarly, call terminations are also registered and affect the active_calls variable.

The goal is to ensure the stream is only triggered when the first active call is dectected, and only stop the stream when the last remaining call is cleared down.

For example, if Phone A calls in, the stream is triggered and starts playing. Then, phone B also calls in and hears the established stream. If Phone A was to hangup, we’ll need to continue the stream for phone B (i.e not latching to the phone that triggered the stream), but if phone B also hangs up, the stream is stopped as there’s nothing there to listen.

Create the script file and add the following:

#!/bin/bash

# Path to Baresip log file
LOG_FILE="/path/to/sipaudio.log"
STREAM_URL="http://edge-bauerall-01-gos2.sharp-stream.com/kerrang.mp3?aw_0_1st.skey=1736072895"

# Track active calls
active_calls=0
mpv_pid=""

start_stream() {
    if [[ -z $mpv_pid ]]; then
        echo "Starting stream..."
        mpv "$STREAM_URL" &
        mpv_pid=$!
    else
        echo "Stream is already running."
    fi
}

stop_stream() {
    if [[ -n $mpv_pid ]]; then
        echo "Stopping stream..."
        kill $mpv_pid
        wait $mpv_pid 2>/dev/null
        mpv_pid=""
    else
        echo "Stream is not running."
    fi
}

monitor_calls() {
    echo "Monitoring Baresip log for call events..."
    tail -Fn0 "$LOG_FILE" | while read -r line; do
        if [[ "$line" == *"Call established"* ]]; then
            ((active_calls++))
            echo "Call incoming. Active calls: $active_calls"
            if [[ $active_calls -eq 1 ]]; then
                start_stream
            fi
        elif [[ "$line" == *"session closed"* ]]; then
            ((active_calls--))
            echo "Call ended. Active calls: $active_calls"
            if [[ $active_calls -le 0 ]]; then
                active_calls=0
                stop_stream
            fi
        fi
    done
}

# Start monitoring calls
monitor_calls

Make the file executatble with:

chmod +x /path/to/filename.sh

Service

This can be ran via the terminal/SSH, but for ease of use and reboot survival, lets create a service for the script.

Create and edit a service file:

sudo nano /etc/systemd/system/sip.radio.service

Add the following to the new service file:

[Unit]
Description=Kerrang Radio Stream
After=sound.target network.target

[Service]
ExecStart=/path/to/filename.sh
Restart=always
RestartSec=10
User=pi
WorkingDirectory=/home/pi
StandardOutput=journal
StandardError=journal
Environment=HOME=/home/pi
Environment=XDG_RUNTIME_DIR=/run/user/1000

[Install]
WantedBy=multi-user.target

When saved, reload services:

sudo systemctl daemon-reload

Start the service and enable it to start at boot:

sudo systemctl enable --now sipradio

Now a test call can be made to the baresip extension, and hopefully the radio will be though in a second or two.

Summary

Since originally starting this in March, the script and SIP endpoint has been idle for a few months, but seeing if it still works while writing this, the stream fired right up on first asking.

I would like to significantly reduce my “smart” speaker density, as they are almost exclusivley music players at this point due to the frustration in using them for anything else (even playing music is a challenge at times), but are always listening in.

To put this theory into production will require both opus capable phone hardware and decent wired/bluetooth speakers with connectivity inbetween.

I wonder if a Pi Zero W2 could come to a cheap option rescue?

]]>
SIP device as Pi Audio Output https://james-batchelor.com/index.php/2025/02/16/sip-device-as-pi-audio-output/ Sun, 16 Feb 2025 16:55:45 +0000 https://james-batchelor.com/?p=992 Continue reading "SIP device as Pi Audio Output"]]> In my Development Den (the spare room) I have a Raspberry Pi 4 setup with a monitor for use as a quick reference station when working on nearby devices.

With no speakers connected this can sometimes pose an issue when trying to follw a tutorial video, and when I do need audio, a Bluetooth speaker is never around.

There is a SIP phone next to the Pi on my desk, and so I thought; that has a decent network connected speaker, why not use that?

This is what ensued…

The idea is to have a SIP endpoint running as a service on the Pi in auto-answer mode. This will allow a desk phone to dial the Pi extension and receive the Pi’s audio through the loudspeaker.

The Pi is running stock Raspbian Bullseye with the desktop environment.

SIP Endpoint

Baresip looks a good choice for this project due to its modularity.

As this will be a service running in the background, only the core module of Baresip needs to be installed:

sudo apt install --no-install-recommends baresip-core

When installed, run the program briefly to have it create its default configuration files:

baresip

This will create the default template files in a .baresip directory within the home folder. We’ll need to edit the accounts and config files to get it to a call answering state.

Starting with the accounts file:

nano .baresip/accounts

Add the following line to the bottom of the file:

<sip:{endpoint}@{sip_server}>;auth_pass={sip_secret};answermode=auto

Where:
{endpoint} – SIP extension number
{sip_server} – IP/hostname of the PBX
{sip_secret} – Extension password

Answermode flag has been added to allow calls to this extension to be answered automatically.

After the accounts file, move onto the config:

nano .baresip/config

This file can be left as default, however a few quality-of-life improvements will be made…

Uncomment the following lines:

module                  opus.so
module                  g722.so

These allow the use of the higher quality codecs commonly in use; g722 is the elder and while it offers higher quality from a phone call audio point of view, may fall short for music. Opus is the newer and can be configured for excellent quality overall, but being newer may not be an available choice on older phones.

If Opus is available, the bitrate can be increased via this line further down the config file (higher bitrate, higher audio quality):

opus_bitrate            28000 # 6000-510000

Make sure both you SIP devices and PBX are capable and configured to offer these codecs at the highest priority.

Testing

Good time for a sanity check, for this an audio file or stream playing through VLC, or any source of audio will do.

Run the application in the terminal

baresip

And make a call to its extension, you should see output in the terminal, and hear the audio through the phone.

If it’s successful, a service can be created to have this running in the background on startup…

Create Service

To allow baresip to start at boot, its best to create a service for it and restart it if it ever stops.

Create and edit a service file:

sudo nano /etc/systemd/system/sipaudio.service

Add the following to this file:

[Unit]
Description=SIP endpoint for Pi audio
After=sound.target network.target

[Service]
ExecStart=/usr/bin/baresip
Restart=always
User=pi
WorkingDirectory=/home/{username}
StandardOutput=journal
StandardError=journal
Environment=HOME=/home/{username}
Environment=XDG_RUNTIME_DIR=/run/user/1000

[Install]
WantedBy=multi-user.target

When saved, reload services:

sudo systemctl daemon-reload

Start the service and enable it to start at boot:

sudo systemctl enable --now sipaudio

With some audio playing, try another call to make sure its answering and picking up audio from the desktop environment.

Conclusion

It’s a niche solution for those who have an audio-less Pi and a SIP phone next to it, but the results are plesently convenient for those rare times when audio is needed.

My accompanying desk phone (Yealink T46S) only offers g722 has the higher codec, but still is perfectly fine for speech output and fine (not great) for audio. I’m sure using Opus at the higher bitrate will put it on par with some of the streaming services. Afterall, YouTube uses opus as audio for its videos, as noted by the “stats for nerds” section:

]]>
Zen Digital Voice – Connecting to SIP https://james-batchelor.com/index.php/2024/11/01/zen-digital-voice-connecting-to-sip/ Fri, 01 Nov 2024 12:15:17 +0000 https://james-batchelor.com/?p=965 Continue reading "Zen Digital Voice – Connecting to SIP"]]> If like me you still have a requirement for a landline, or at least a landline number. Zen Internet offers a “digital voice” package as an accompaniment to its broadband service.

Traditionally this service is provided via its supplied Fritzbox router, utilising its FXS port to supply telephony to analogue devices.

As the service is SIP based, it is possible to connect direct via SIP phones or Asterisk which is ideal should the Fritzbox not be suitable for your requirements. While this is permitted by Zen, it is unsupported.

Here are a couple of examples of getting connected to Zen DV without the use of the Fritzbox.

A Pre-Setup Warning

This process involves exposing a SIP server / device to the internet, this protocol is constantly targeted by hackers and fraudsters due to its reward for exposing a vulnerable system.

For example, hackers can exploit a system to generate high volumes of calls on your account for either their own benefit (calling a premium rate number they setup) or for the sheer fun of it, while fraudsters could use your “line” to make robocalls to other phone numbers.

Therefore, it is imperative to limit the service’s exposure to only the IP’s listed below, if your router is unable to open ports to specified addresses, consider upgrading or not proceeding.

Network

From a network point of view, VoIP is split into two sections; Signalling (SIP) that deals with the actions of a call, such as “start ringing” and “hangup now”. The Media (RTP) solely deals with the audio of the call and its setup is defined via the SIP signalling.

Uniquely For the DV service, Zen employs a separate server each for inbound and outbound calls:

SIP Inbound:
voip.zen.co.uk – 212.23.7.228

SIP Outbound:
voip2.zen.co.uk – 212.23.7.235

Media uses a common range:

RTP Media:

62.3.88.0/28
62.3.88.16/28

Ports used by the service are the standard:

SIP: 5060
RTP: 10000 – 20000

Setup

As we are trying to mimic the Fritzbox, which is the first point of contact from the internet, the above ports need to be passed onto your SIP device. As this could pass any internet traffic on these ports to the device it’s a good idea to limit these open ports to only the IPs above too.

This will differ depending on the router used, as an example this is how to set it up on a Draytek router:

Allowed Client List / Whitelist

In the router’s web interface, navigate to Objects Setting >> IP Object, add the IPs:

These need to be grouped together, in Objects Setting >> IP Groups, add these IPs into the group:

Open Ports

Now there is a list of allowed IPs, the ports can be opened, in NAT >> Open Ports, edit an index, setting:

WAN Interface: Port connected to Zen internet
Source IP: The group created above
Private IP: Local IP of SIP device
Ports: Open UDP ports 5060 and a range 10000-20000

Now VoIP traffic is forwarding to the device, it can be configured…

SIP

To authenticate with the service the phone number {number} (full number including area code, in national format, i.e starting 01 or 02) will be used as the username, and you’ll need the password {password}(secret). The password is available via the old Zen portal for legacy customer (https://portal.zen.co.uk/) or by contacting Zen and asking for “your VoIP password”.

Asterisk

As there are two servers in use for SIP signalling, two trunks are required on the PBX:

Trunk 1 – Inbound; This just needs to accept calls from Zen’s server so is pretty basic:

type=peer
trustrpid=yes
nat=yes
insecure=invite
host=voip.zen.co.uk
disallow=all
allow=alaw

Trunk 2 – Outbound; This contains authentication to login (register) to the service and make calls:

type=peer
secret={password}
host=voip2.zen.co.uk
fromuser={number}
disallow=all
authuser={number}
allow=alaw
nat=yes
insecure=invite
fromdomain=voip2.zen.co.uk
defaultuser={number}

The outbound trunk also requires the registration details, this allows Zen’s servers to recognise that your service is online and ready for calls:

{number}:{password}@voip2.zen.co.uk/{number}

If you’d like to monitor the connection, you’d see this in sngrep:

Note even when setup correctly, the initial registration attempt will fail as Asterisk attempts to register without authentication, upon the 401 error it will then attempt registration with authentication details and receive the 200 OK response and so registered to the service.

SIP Phone

To connect directly to SIP device, it’s mainly a case of just getting the phone to register, from there the Zen server will know it is logged in for calls and take it from there. The generic details needed are below, apply this best to the terminology used by the device:

Username / Register Name: {number}
Password / Secret: {password}

Server / Registrar / Host: voip2.zen.co.uk
Transport / Protocol: UDP
Port: 5060

For example, this is a setup of a Yealink phone:

If setup correctly, the registration status should state “Registered”.

This is for Yealink devices but will likely be applicable for other vendors, you will need to change the following settings in Features >> General Information:

Accept SIP Trust Server Only: This needs to be disabled as inbound calls come from a different server than the device is registered to.

Allow IP Call: Important to disable especially if there is no IP whitelisting on the router, this stops random or “ghost” calls generated by hackers trying to find a response from internet facing phones. This will not be an issue if you are able to restrict open WAN ports to allowed IP’s, but if not, this helps.

Conclusion

Setup, you should be able to use your Zen DV number with your VoIP / SIP devices.

For a single phone this is a simple solution, but for multiple phones around the home your either limited to only cordless phones from the likes of Yealink or Gigaset (where the base unit is the controller and SIP registration device).

But for a combination of landline and cordless, the VoIP revolution means the end of an era of running an extension cable to the next phone, you’ll need a local PBX of some sort to handle signalling.

Finale

This is also likely an end of an era for my VoIP based posts, as I have left my telecoms role for something different.

I may return sporadically to VoIP postings if I find a home use for it, or revive a post that didn’t quite get there. But for now, it’s a goodbye to SIP.

]]>
Asterisk Monitoring Over SNMP https://james-batchelor.com/index.php/2023/12/28/asterisk-monitoring-over-snmp/ Thu, 28 Dec 2023 15:36:05 +0000 https://james-batchelor.com/?p=927 Continue reading "Asterisk Monitoring Over SNMP"]]> The aim of deploying Zabbix and adding SNMP to Gentoo was to gain better insight on how an Asterisk PBX was performing.

Last of the hurdles was to get data from Asterisk in order to send to Zabbix, however the traditional way of loading the res_snmp.so module in Asterisk was not available, as while the PBX in question utilises Asterisk, its buried under proprietary licensing and a non-standard api, therefore being unable to either add the SNMP module or to query it.

If you are experiencing a similar situation, here is how to extract some stats from Asterisk 16 using SNMP, but without the SNMP module…

Despite not being able edit Asterisk code directly, SSH access and the Asterisk CLI is available, so can run commands to return a snapshot of PBX activity.

The following commands can be run to output some valuable info:

asterisk -rx ‘pjsip show endpoints’ returns total number and current online endpoints, as well as reported user agent of device.

asterisk -rx ‘core show channels verbose’ gives us a list of active channels and current point in an inbound call flow, along with a counter of completed calls.

asterisk -rx ‘pjsip show channelstats’ is similar to ‘show channels verbose’, but includes the codec in use, helpful to determine if the system is transcoding.

Scripts

To get and output just the info required, a script can be created to parse the command output and list each value on a new line.

Create the three files below and paste the code in.
In this example I saved to /usr/local……

asterisk_chan.sh

command_output=$(asterisk -rx 'core show channels')

active=$(echo "$command_output" | grep -oE '[0-9]+ active channels' | grep -oE '[0-9]+')
processed=$(echo "$command_output" | grep -oE '[0-9]+ calls processed' | grep -oE '[0-9]+')

echo "$active"
echo "$processed"

asterisk_chanstat.sh

command_output=$(asterisk -rx 'pjsip show channelstats')

opus=$(echo "$command_output" | grep 'opus' | (wc -l))
g722=$(echo "$command_output" | grep 'g722' | (wc -l))
alaw=$(echo "$command_output" | grep 'alaw' | (wc -l))
ulaw=$(echo "$command_output" | grep 'ulaw' | (wc -l))
g729=$(echo "$command_output" | grep 'ulaw' | (wc -l))
total=$(echo "$command_output" | grep -oP 'Objects found: \K\d+' || echo 0)

echo "$opus"
echo "$g722"
echo "$alaw"
echo "$ulaw"
echo "$g729"
echo "$total"

asterisk_endpoint.sh

command_output=$(asterisk -rx 'pjsip show endpoints')

avail=$(echo "$command_output" | grep 'Avail' | (wc -l))
total=$(( $(echo "$command_output" | grep -c 'Endpoint') - 1 ))

echo "$avail"
echo "$total"

Saved, they need to be made executable, add the execute flag to each file…

chmod +x /usr/local/asterisk_chan.sh
chmod +x /usr/local/asterisk_chanstat.sh
chmod +x /usr/local/asterisk_endpoint.sh

SNMP extend_sh

SNMP has an extension feature to add and poll your own custom data, to take advantage of this the snmp.d.conf file need to include reference and path to the scripts. At the bottom of snmpd.conf, add the following lines…

extend-sh asterisk_chan /usr/local/share/snmp/rps/asterisk_chan.sh
extend-sh asterisk_chanstat /usr/local/share/snmp/rps/asterisk_chanstat.sh
extend-sh asterisk_endpoint /usr/local/share/snmp/rps/asterisk_endpoint.sh

Restart snmpd to load changes…

Gentoo:

/etc/init.d/snmpd restart

RHEL:

systemctl restart snmpd

Testing

Using snmpget command locally or on your collector machine, test that its working..

snmpget -c }your-community} -v 2c {ip-address} 'NET-SNMP-EXTEND-MIB::nsExtendOutLine."asterisk_chan".1'

Where “asterisk_chan” is the name of the extend_sh created in snmpd.conf file, and .1 on the end collates to the line of script output, .2 returns the second line and so on.

Add to monitoring

When adding to your monitoring system, in this example Zabbix, use the command listed in the testing phase to grab the values…

Logging and monitoring is now enabled for the Asterisk service…

]]>
Yealink OpenVPN to Draytek Router https://james-batchelor.com/index.php/2022/11/13/yealink-openvpn-to-draytek-router/ Sun, 13 Nov 2022 17:12:20 +0000 https://james-batchelor.com/?p=839 Continue reading "Yealink OpenVPN to Draytek Router"]]> The firewalls in front of our PBX’s are configured to only allow SIP traffic from UK IP addresses, this reduces the attack surface and is usually not an issue as almost all legitimate traffic is from the UK.

As we expand there is greater need for international connections, this is fine if they have a static WAN IP or FQDN, but the more recent requirements are for “home” users with phones on their residential connections where dynamic IPs are the standard.

Changing the whitelisted IP every time their IP changes is not only tedious, but gives poor service, plus due to recent events (here and here) I’m not prepared to open access to another country for a single extension.

In my case, these internationals are satellites of a UK based office, so the idea is having the overseas phone route all voice traffic through the UK office where its free to connect to the PBX…

For this setup, a Yealink T46S will connect to a Draytek 2927 via OpenVPN and crucially, route all traffic destined for the PBX via the VPN to get around the GeoIP block.

This guide should also be compatible with the Draytek 2865, and Yealink T4xS and T4xU series phones.

Notepad++ and 7zip are required.

Draytek Setup

Original Guide: https://www.draytek.com/support/knowledge-base/7462

First create a user for the Yealink, at the router GUI navigate to: VPN and Remote Access >> Remote Dial-in User.

Click an Index number and make the following changes:

  • Enable this account: On
  • Allowed Dail-In Type: OpenVPN Tunnel: On
  • Username: Enter a username
  • Password: Enter a password

It should look like this:

Next is to setup the Draytek to accept OpenVPN connections.

Navigate to VPN and Remote Access >> Remote Access Control. And check OpenVPN is enabled.

Then navigate to VPN and Remote Access >> OpenVPN >> OpenVPN Server Setup.

In the General Certificates section, select Router Generated Certificates, and then press generate.

After some time, the generated certificates appear in this section:

OpenVPN Setup

The Draytek has the ability to create an OpenVPN config file for clients. However, what the Draytek generates and what the Yealink requires is not compatible. Therefore, we’ll need to manipulate the file to file to get what we want.

Extracting Certificates

On the Draytek, navigate to Remote Access >> OpenVPN >> Client Config.

Leaving defaults in place, enter a filename and click the Export button to download the config file.

Open the file in Notepad++.

You’ll see the protocol config at start of file, followed by each of the certificates in the following order:

  1. CA
  2. Client
  3. Private Key

The Yealink requires the certificates in their own file so they need to be extracted.

Copy the text from —–BEGIN CERTIFICATE—– to —–END CERTIFICATE—– of the first certificate and paste into a new Notepad++ file.

Save this file as ca.crt (remove the txt file extension)

Repeat this for the second certificate, naming this one client.crt

Now it’s the private key, copy text from —–BEGIN RSA PRIVATE KEY—– to —–END RSA PRIVATE KEY—– to a new file and save as client.key

Config files

For the next file, you’ll need to add the Draytek VPN user details as a file to allow the Yealink to authenticate.

In a new text file, enter the username and password on separate lines as below:

Save the file as auth.txt

You’ll now have the following files:

With the supporting files ready, it’s time to reference them together with the OpenVPN config file.

In a new text file, enter the following info:

client
dev tun
proto udp
remote nnn.nnn.nnn.nnn 1194                  # IP address of Draytek
auth sha256
cipher aes-256-cbc
resolv-retry infinite                        # Reconnect if dropped
nobind

ca /config/openvpn/keys/ca.crt
cert /config/openvpn/keys/client.crt
key /config/openvpn/keys/client.key

auth-user-pass /config/openvpn/keys/auth.txt

persist-key
persist-tun

route nnn.nnn.nnn.nnn 255.nnn.nnn.nnn nnn.nnn.nnn.nnn  # Static route:
                                                       # PBX IP
                                                       # IP Subnet
                                                       # Draytek LAN Gateway
verb 5

Save this as vpn.cnf

Preparing Yealink File

Original Guide: https://support.yealink.com/forward2download?path=ZIjHOJbWuW/DFrGTLnGypjZRKhDplusSymbolXJQ4JaUSvKXmAoZw0rMev5uUPSPDoclfqojerLoiDU/Ol0NW5DZdXcWplusSymbolZDNbde0dvqwZjDVChAjsaqHDjPW14991UaBvXhQ10P6Rm4u3tO4pNBqXRzzyvj9PbA==

The OpenVPN configuration is uploaded to the Yealink via a specifically arranged tar file, so the directory structure needs to be prepared.

On your desktop, create a new folder (named anything you like) and within this folder create another named “keys”

Move vpn.cnf to the upper folder, and move auth.txt, ca.crt, client.crt and client.key to keys directory.

Open 7-Zip and navigate to the newly created folder:

Highlight vpn.cnf and keys, right click and choose 7-Zip >> add to archive.

Ensure the following is set:

  • Archive format: tar
  • Compression level: Store

Click OK to create the file. The tar file is created in the directory and it’s ready to be uploaded to the Yealink

Yealink Setup

On the phone, press the OK key to discover it’s IP address, then navigate to it’s Web interface via a browser on your computer.

Login, then move to Network >> Advanced and scroll down to the VPN section.

Set Active to Enabled and set Mode to OpenVPN

Click browse next to Upload VPN Config and choose the created tar file.

Click Upload, the page will refresh and now Upload VPN Config is populated with vpn.cnf

Click Save at the bottom of the page.

OpenVPN will be set back to Disabled, scroll down and Enable it again, then click Save.

As there’s a network change pending, you’ll need to click apply at the warning message:

It’ll now connect to the VPN.

Note: If you are configuring a phone remotely, the web page will stop responding as traffic is now passing through the VPN. To get back to the interface, check the Draytek for the VPN connection (VPN and Remote Access >> Connection Management) to discover it’s local IP:

The phone is now connected and routing traffic via the VPN.

]]>
Provisioning Polycom Phone https://james-batchelor.com/index.php/2021/08/10/provisioning-polycom-phone/ Tue, 10 Aug 2021 12:08:31 +0000 http://james-batchelor.com/?p=747 Continue reading "Provisioning Polycom Phone"]]> Yealink is our go to vendor for telephony hardware, mainly due to its ease and variety of configurability. But recently have been tasked with adding a Polycom VVX250 to the system for a charity to use.

While the setup between different manufacturers normally follows the same general path. This is a journey of how Polycom interprets it…

Factory Booting

As these are inerited devices, they were pre-configured to another system and default passwords changed. Luckily (For us anyway) Poly’s implementation still allows a phone to be factory reset even if preconfigured.

To factory set a Poly VVX250:

  1. Reboot or power on phone.
  2. At the “starting application…” screen, press the cancel button.
  3. It will now start a countdown, during this press and hold 1, 3 and 5 on the dialpad, it will now prompt for a password.
  4. Enter the device MAC address as the password.
  5. Press okay, it should notify that the device is factory reset.

Zero Touch Provisioning

A feature many manufacturers have is a auto-provision or zero touch provisioning system. As these are going to be the only Poly’s on the system there would be little gain in investing in their service.

To the rescue will be DHCP options, mainly opt. 66 for Boot Server, where we will steer an unprovisioned device to the phone system.

Here, add DHCP option 66 to your DHCP server, and add an ASCII value of the address of you phone server, complete with any authentication string.

Configuration

While Yealink’s are pretty usable out of the box, Polycom’s require a bit more fettling to get into a working state.

A lot of this fettling is required via the config files it attempts to pull from the provisioning server. Starting with:

Firmware:

Firmware loaded on the phone dictates what files a phone will request from a provisioning server, which I’ve found causes issues when a mismatch of device firmware levels are introduced to a system.

Therefore a a matching firmware level server/client side is required. For this example I used an older 6.1.0.6163 fw that was compatible with our system.

Config Files:

Our system, like many modern PBX’s generate a config file on the fly, negating the need to store all config files individually.

In this case, while the {MAC}.cfg file can be auto-generated, the site.cfg (system level config) file is not and so has to be manually edited. The connotations of this in a multi-tenant environment means that a lot of customisations are not available, such as wallpapers and even directories.

Dial Plan:

As discovered during testing, a clean Poly device will include a US specific dialplan as default. This causes issues with both UK PSTN calls and local extension calls, sending the call after on 2 digits dialled.

Therefore a new dial plan has to be created and added manually to site.cfg. This was my interpretation:

999 emergency
1xxT emergency, 3 digit NSN

[1-8]xxxT pbx extensions
*xxT pbx star codes
*xxxT pbx star codes

116xxx 6 digit (excl directory enq)
08[04]xxxxT 7 digit NSN
0[18]xxxxxxxT 9 digit NSN
0[12358]xxxxxxxx 10 digit NSN landline
07[1-9]xxxxxxx 10 digit NSN mobile (excl personal numbering)

00x.T International

This translated into the the following strings for the Polycom:

Polycom dialplan string:
999|1xxT|[1-8]xxxT|xxT|xxxT|116xxx|08[04]xxxxT|0[18]xxxxxxxxT|0[12358]xxxxxxxxx|07[1-9]xxxxxxxx|00x.T

Polycom dial timeout string:
3|3|3|3|3|3|3

Testing

With the above configuration the Poly VVX250 performs as a budget phone normally would.

A small issue I think customers would fall prey to is the “URL” labelled button that appears when number input is required (calling / transferring), when pressed it changed the dial pad into T9 input and would imagine being confusing if the URL press was unintentional.

Apart from that, the lack of customisation options in a multi-tenant environment and the cost of the phone compared with its usable feature set would likely rule it out as a product to offer for our platform.

]]>
Provisioning a Cisco 7940/7960 https://james-batchelor.com/index.php/2021/01/23/provisioning-a-cisco-7940-7960/ Sat, 23 Jan 2021 18:39:58 +0000 http://james-batchelor.com/?p=736 Continue reading "Provisioning a Cisco 7940/7960"]]> 2021 is here and so returns (In the UK at least) one of my favourite shows to Netflix, The Office (US). Since starting working in VoIP its hard not to notice what phones turn up in TV shows, here the Cisco 7960, was prolific for showing up in shows around this era.

So why not, nearly 16 years after the show started, try and get one of these working on an Asterisk PBX? At work we had a number of similar 7940 models that hadn’t be used for years, so why not give it a try…

History

When the show started in 2005, these phones would need an entire Cisco ecosystem to support it, as it was essentially locked to Cisco’s propriety SCCP system. It was later and when the models were approaching end of life that a firmware update allowed it to communicate over SIP, therefore making it compatible with many more systems.

Before going further, I should note that I the telephony world, these things are ancient and have fallen way behind the capability that modern phones can offer. I would recommend these as a novelty and not be considered for deployment as it requires a lot of manual setup for little return, as we’ll go into….

Requirements

PBX: SIP based, for this example I’ll be using FreePBX, based on Asterisk.

Firmware: Dependent on what’s already loaded on the phone, you may need to source the P0S3-8-12-00 firmware that enables SIP. It can still be found with enough searching online.

TFTP Server: The 7940 can only be configured via TFTP and cannot be setup manually on the phone, so this is essential. In this example I’ll be using Windows Server 2019 and repurposing the TFTP element of Windows Deployment Services.

DHCP Options: The phones are pointed to the TFTP server via DHCP Options, a router or DHCP server capable of these is required. I’ll be setting this up on a Draytek 2862.

HTTP Server: Should you wish to add Services and a Directory, the phone pulls this information via HTTP.

Setup

TFTP Server

In Windows Server 2019, open Server Manager and start the Add Roles and Features Wizard.

In Server Roles, tick Windows Deployment Services

Then in Role Services, select just Transport Server to enable TFTP.

By default, Windows uses TFTP exclusively to deploy Windows images on client machines, so we’ll need to make a registry edit to allow the server to provide all files.

Open RegEdit, and navigate to:

Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WDSServer\Providers\WDSTFTP

TFTP files are served from C:\RemoteInstall by default, this can be changed by editing RootFolder value.

Edit ReadFilter value to add \* to allow all files to be read in the root folder.

To re load these changes, restart Windows Deployment Services Server from the Services folder.

DHCP Options

To allow the phone to know where the TFTP server is on boot, DHCP Option 150 is used to direct the phone.

Logged into the Draytek 2862, navigate to LAN –> General Setup –> DHCP Server Option button.

Enter Option Number 150, and enter the server IP address in the Data field:

To check its working, plug the phone into the network, after initial loading it will start looking for files at the server’s IP address.

Config Files

All of the phone’s functionality is provided by the config files. As a minimum the phone requires the following for use with SIP:

SIPDefault.cnf – Common configuration for all phones on the network, containing info such as SIP server.

SIP<MAC Address>.cnf – Phone’s individual config, such as extension registration info. File is named SIP001D45000000.cnf where 001D45000000 is the MAC address of the phone.

If your phone is loaded with SCCP firmware, for instance if it was pulled from a Cisco infrastructure environment, the phone will attempt to pull a different set of files from the TFTP server.

To identify SCCP firmware, when loading the top black bar will lack the “SIP” logo on the right.

If it is the older firmware, additional files are needed to instruct the phone to update its firmware:

XMLDefault.cnf.xml – First file served, specifies the firmware to load.

OS79XX.TXT – An alternative firmware pointer file.

Then you will need the firmware files, for reference / search purposes, these are the files needed:

P0S3-8-12-00.loads
P0S3-8-12-00.sb2
P0S3-8-12-00.tar
P0S3-8-12-00.bin
P0S3-8-12-00.sbin

Factory Reset

If the phone already loads and gives an extension, it will need to be factory reset:

With the phone unpowered, hold the # key. While holding, connect power to the phone and release the # key when the Headset, Mute and Speaker buttons start lighting in sequence.

Next whiles lights are still in sequence, press 123456789*0#.

When reset menu appears, press 2 to say no to keep network settings.

Phone will reboot and is ready to provision.

Provisioning

DHCP Option, TFTP Server, files in place, the phone can now be provisioned.

Dependant on firmware level it will take up to 5mins to upgrade and provision, during which and if all goes well will get some comforting references to the files served by the TFTP server.

You now have a Dunder Mifflin issued extension.

]]>
Testing a New PBX https://james-batchelor.com/index.php/2020/02/22/testing-a-new-pbx/ Sat, 22 Feb 2020 21:32:52 +0000 http://james-batchelor.com/?p=648 Continue reading "Testing a New PBX"]]> Recently I’ve had the opportunity to deploy and test a call centre PBX product to gauge if its viable to offer as a product and how it will sit within our infrastructure.

Installing and poking around the GUI is all well and good but to really find out how a PBX behaves it needs some traffic, to find outs its performance in regards to resources but also to find out what a vendor’s interpretation of an advertised feature actually is.

To generate sample calls, instead of registering handsets/softphones and dialling manually it would be better to automate this, and SIPp is the perfect tool for this.

SIPp is an open source SIP testing tool for stress testing PBX’s, but it can also be used more modestly so it can generate more real-world scenarios to simulate typical calls. This can also be beneficial when testing and reviewing complex call flows through a system before deploying.

Environment

In this example I would be using a local CentOS 7 Virtual Machine to host the SIPp application, with the PBX sitting remotely and network access via VPN for the testing period.

The PBX will also have a trunk set to allow calls in from the CentOS box and a DDI assigned.

Installation

Installation on CentOS is easiest via yum and the EPEL repositories.

From a clean install run:

yum update
yum install epel-release
yum install sipp

Operation

Once installed its as easy to run as running the program from the command line, but getting the results you are looking for requires a lot of switches and a scenario file.

SIPp in action

The simplest way to look at this is the switches take care of the targeting and rate of the calls, where the scenario file simulates the calling person, and can be set to imitate speech (RTP streams), dtmf inputs and even introduce packet loss to measure quality of calls. Essentially a profile of a call is contained within the scenario file.

As an example, this is a typical command I use for testing a very modest call load:

sipp -sf file.xml -trace_err -trace_msg -i 10.20.30.40 -r 1 -rp 10000 -l 100 -m 50 -s 12345678901 10.100.100.100

To break down this command and make it more understandable:

  • -sf {FILENAME} – Scenario file.
  • -trace_err – Print errors to file, for troubleshooting.
  • -trace_msg – Print verbose log to file, for troubleshooting.
  • -i {IPADDRESS} – RTP stream (Audio) source.
  • -r {NUMBER} – Call Rate – Rate that calls are attempted.
  • -rp {NUMBER} – Rate Period – Number defined in Call Rate are spread over the Rate Period.
  • -l {NUMBER} – Max number of concurrent calls.
  • -m {NUMBER} – Total number of calls to attempt.
  • -s {NUMBER}- SIP number to dial and server.
  • “10.100.100.100” – PBX server IP

Scenario File

As mentioned, the scenario file contains the simulation of a call from a calling party.

SIPp has a number of template scenario files in XML format available on their Sourceforge page, these can be download and modified as needed.

For example, below is my modification of the uac_pcap.xml template, this is a simple file that connects and plays an RTP stream (from a pcap file) for two minutes before hanging up:

  <scenario name="UAC with media">
<!-- CALL SETUP         -->
  <send retrans="500">
    <![CDATA[
 
      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
      From: 01234567890 <sip:01234567890@[local_ip]:[local_port]>;tag=[call_number]
      To: sut <sip:[service]@[remote_ip]:[remote_port]>
      Call-ID: [call_id]
      CSeq: 1 INVITE
      Contact: sip:sipp@[local_ip]:[local_port]
      Max-Forwards: 70
      Subject: Performance Test
      Content-Type: application/sdp
      Content-Length: [len]
 
      v=0
      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
      s=-
      c=IN IP[local_ip_type] [local_ip]
      t=0 0
      m=audio [auto_media_port] RTP/AVP 8
      a=rtpmap:8 PCMA/8000
      a=rtpmap:101 telephone-event/8000
      a=fmtp:101 0-11,16
 
    ]]>
  </send>
 
  <recv response="100" optional="true">
  </recv>
 
  <recv response="180" optional="true">
  </recv>
 
  <send>
    <![CDATA[
 
      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
      To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
      Call-ID: [call_id]
      CSeq: 1 ACK
      Contact: sip:sipp@[local_ip]:[local_port]
      Max-Forwards: 70
      Subject: Performance Test
      Content-Length: 0
 
    ]]>
  </send>
  <!-- PLAY RTP STREAM         -->
  <nop>
    <action>
        <exec play_pcap_audio="pcap/g711a_600.pcap"/>
    </action>
  </nop>
 
  <!-- SET CALL LENGTH                                                        -->
  <pause milliseconds="120000"/>
 
  <send retrans="500">
    <![CDATA[
 
      BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
      To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
      Call-ID: [call_id]
      CSeq: 2 BYE
      Contact: sip:sipp@[local_ip]:[local_port]
      Max-Forwards: 70
      Subject: Performance Test
      Content-Length: 0
 
    ]]>
  </send>
 
  <recv response="200" crlf="true">
  </recv>
 
  <!-- definition of the response time repartition table (unit is ms)   -->
  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
 
  <!-- definition of the call length repartition table (unit is ms)     -->
  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
 
</scenario>

Personal Observations

This is a great tool for automation in the testing phase of a new platform deployment, and you can easily generate calls in numbers considered unfeasible when using traditional desk and soft phones, plus this method allows all phones in the test bed to become call recipients, increasing the user base to more accurately test a platform.

In addition to the PBX this tool also tests the network that provides connectivity to the phone system, this was highlighted to me when testing with traffic going over a VPN, and discovered that the VPN gateway could not cope with more than 10 concurrent calls despite having enough bandwidth available.

As a final note I recommend to start a test with minimal call volume ad scale from there. Whilst SIPPp can simulate calls, these aren’t as organic as the real world. I managed to knock a live system offline with as little as 100 generated calls, due in part to 100 SIP invites being sent within one second.

Oh, and don’t introduce a load of test calls to a flow where the final destination is a voicemail, I found that out the hard way!

]]>
Yealink Remote Factory Reset https://james-batchelor.com/index.php/2019/07/06/yealink-remote-factory-reset/ Sat, 06 Jul 2019 16:27:46 +0000 http://james-batchelor.com/?p=602 Continue reading "Yealink Remote Factory Reset"]]> When a phone is no longer required on your service, there is always trepidation on what will happen to it, the hope is that’s its unplugged, stuffed in a drawer and never sees the light of day again. But in reality, there’s a good chance that it will end up on the likes of eBay and Gumtree, and since a phone is already provisioned with your server details, the next person to get their hands on it could have unauthorised access to the system.

The simple step to prevent unauthorised access is to delete / change the secret to the extension, if your will to put up with the constant failed registration attempts. But what about the personal data on the phone? BLFs, local directories and the like.

Yealink devices since firmware version 81 have had the ability to factory reset via a SIP notify command, meaning should a phone still be online, a factory reset can be handled remotely and without end user intervention.

Phone Setup

Remote reset is disabled by default, to enable it add the following to the provisioning template:

sip.notify_reset.enable = 1

Note: If you’d like to incorporate this with new deployments, ensure you also add the following to ensure sip notify commands are only trusted from registrar server.

account.1.sip_trust_ctrl = 1

PBX Setup

Via SFTP, Log in to the PBX and navigate to /etc/asterisk to locate the sip_notify.conf file.

Here there may be a few variants of the sip_notify.conf, such as sip_notify_additional.conf and sip_notify_custom.conf, choose the variant that does not contain the “do not edit” warning within the contents.

Choose the correct .conf file

In the correct file, add the following lines of code:

[yealink-reset]
Event=>reset

Next, log into the CLI (command line interface) of the PBX via SSH.

Enter asterisk -rvvv to open the Asterisk CLI at verbose level 3.

Enter reload to load the newly added code into the system.

Resetting

Now the reset command can be issued in the Asterisk CLI:

Asterisk Versions 1-3:

Sip notify yealink-reset NNNN

Asterisk Versions 13 onwards:

pjsip send notify yealink-reset endpoint NNNN

Where NNNN is the phones’ extension number.

All things well, you will get conformation of the Notify command being send, shortly followed by the device dropping offline.

Note: If you take advantage of the Yealink Remote Provisioning Service, remember to remove the device or enter sinkhole credentials, otherwise the phone will re-provision and come straight back to you.

]]>