Imagine being able to listen in on your scanner from any location with internet access, or “on the go” on your mobile device.

This article explains how you can turn your scanner into a web radio, for broadcasting online. In this tutorial we will implement the following features:

  • continous 24/7 streaming
  • voice activated recording on external USB stick
  • daily log with timestamped entries of logged frequencies
  • management of Icecast / monit / webmin through web interfaces

Scanner receiver

Since we will be picking up more than just one frequency, it will be good to know which that frequency is. We need some way to communicate with the scanner, that’s why the serial port is very useful.

There is a simple communications protocol used by Uniden to interact with their radios. A very useful feature is the radio’s ability to inform us whenever the squelch has broken. This will save us from having to poll the radio during regular intervals! And our python script will be event triggered basically by the radio itself to query the radio about the current frequency. This information will then be passed to Icecast’s server metadata information. Streaming players that can handle this information will then display this metadata which is normally used for the current playing song title. We will instead send the currently reported frequency!

Selecting hardware

When selecting a device for a streamer, keep in mind that you will need a integrated sound card, or you will need an external “add on” USB sound card. A serial port is also recommended if possible for reasons that will be explained above.

As a streaming device I chose the DreamPlug from Globalscale, but any other Linux single board computer will do. Here you can see how it compares to other boards out there. DreamPlug has a single core 1.2 GHz ARM processor with a half GB of RAM. As you can see from the pictures below it offers a lot of connectors but of most importance to us is the microphone input and the LAN port.

Since our device will be online 24/7 its important to keep power consumption as low as possible, not only for the electrical bill, but also since we want our setup to be environmentally friendly! Power consumption is an incredible 5 Watt! (1 A @ 5V)

Streaming software

The software we will use is freely available online from open source projects. Configuration does require some more fiddling on your part and doesn’t work straight “out of the box”, but that is also the fun part of putting all the pieces together.

On my setup, audio streaming is performed with the following software:

Icecast2 – streaming server software for streaming multimedia clients to connect to

DarkIce – a live audio streamer. It records audio from an audio interface (e.g. sound card), encodes it and delivers it to a streaming server.

Two programs are therefore involved in audio streaming. The streaming server (IceCast2) accepts connections from two entities. The audio streamer (DarkIce) which provides the source of the audio. And the clients (VLC/Winamp) who connect to the server to access this audio stream. In a home setup, these two usually coexist in the same machine. If you intend to have a large scale deployment though you could outsource the server part (which puts higher demands on hardware and especially bandwidth).

General overview of the setup.

Icecast Configuration

The Icecast service is configured through an XML formatted file /etc/icecast2/icecast.xml
Here you have to pass critical information, such as the credentials for

  • optional password for the audio feeds
  • required password for the sources providing the streams (darkice)
  • required password for the administrator login in through the web interface In my setup the mountpoint is called “/live”.
    I noticed that you can totally omit the mountpoint information, in that case it will be created with whatever information is supplied by darkice (assuming the souce password is correct)

Darkice Configuration

The Darkice client is configured through a normal configuration file. If you don’t find it in /etc/darkice.cfg , create it with contents similar to:

[general]
duration = 0 # duration of encoding, in seconds. 0 means forever
bufferSecs = 5 # size of internal slip buffer, in seconds
reconnect = yes # reconnect to the server(s) if disconnected

# this section describes the audio input that will be streamed
[input]
device = default
sampleRate = 8000
bitsPerSample = 16
channel = 1     # channels. 1 = mono, 2 = stereo

# this section describes a streaming connection to an IceCast2 server
# there may be up to 8 of these sections, named [icecast2-0] ... [icecast2-7]
# these can be mixed with [icecast-x] and [shoutcast-x] sections
[icecast2-0]
bitrateMode = cbr # average bit rate
format = mp3 # format of the stream
bitrate = 32 # bitrate of the stream sent to the server
server = localhost # host name of the server
port = 8000 # port of the IceCast2 server, usually 8000
password = hackme # source password to the IceCast2 server
mountPoint = live # mount point of this stream on the IceCast2 server
name = GerakiATC # name of the stream
description = Live Air Traffic Control # description of the stream
url = http://www.tekmanoid.com # URL related to the stream
genre = scanner # genre of the stream
public = no # advertise this stream?a

Additional programs used

Monit is program that monitors the “health” of deamon processes / servers by keeping an eye on CPU / memory usage, response or the lack of it to a service port. In my configuration its used to monitor the IceCast / DarkIce processes.

  • Icecast: check that port 8000 responds to HTTP request and that process is up and running -else, report and restart process.
  • DarkIce: check that process is up and running. DarkIce is configured as a process that depends on IceCast and restarts BOTH if one has failed.

Additionally I added the option to be informed by email whenever the state of these programs change. You have to know the SMTP server settings for this.

screen is a “window manager”. In this project it is used to start the Python scripts and let them output to stdout. It allows the user to execute the program and then “detach” from the screen while the program is still running in the background.

serproxy  is a program that redirects serial ports to network ports. Most programming languages have well defined ways of creating sockets for connecting to network interfaces. Serial ports can be more challenging. That is where serproxy comes in to simplify things. Configuration file /etc/serproxy.cfg

root@dreamplug:~# cat /etc/serproxy.cfg 
# Config file for serproxy
# See serproxy 's README file for documentation

# Comm ports used
comm_ports=1

# Default settings
comm_baud=19200
comm_databits=8
comm_stopbits=1
comm_parity=none

# Idle time out in seconds
timeout=300

# Port 1 settings (ttyS0)
net_port1=5331

ddclient is a deamon program used to update DNS entries whenever it detects a change in the assigned public IP. Most home routers allow this configuration through their own interface, and you can select that option if you want.

# Configuration file for ddclient generated by debconf
#
# /etc/ddclient.conf

protocol=dyndns2
use=web, web=checkip.dyndns.com/, web-skip='IP Address'
server=dynupdate.no-ip.com
login=yourusername
password='hackme'
myregistered-dns-name.com

usbmount used to automatically and safely mount and unmount pen-drives, used here as external media for storing our voice activated recordings. USB devices will be assigned the following mountpoints /media/usbX where X is a digit from 0 to 7.

Free serial port connected to console, for connection to radio’s COM port

The COM port is already internally “wired” to the linux console, as a last resort connection mechanism in case the SSH service should fail for some reason, ban you, or any other reason. NOTE: For communicating with Dreamplug (or any other “plug PC” for that matter) using another PC port, you will have to connect the two using a null-modem cable, and not a classic serial port extension cable.

Lets assume now that nothing will ever go wrong with our SSH connections and “disconnect” our COM port from the console and use it like we please.

First check the current settings of the COM port:
stty < /dev/ttyS0
Check also whether a process is already using the COM port:

 ps -ef | grep tty
 root  2061  ttyS0    00:00:00 /sbin/getty -L ttyS0 115200 linux

This process is started during system startup from the /etc/inittab file. In it we find indeed the following line:

# Example how to put a getty on a serial line (for a terminal)
 T0:23:respawn:/sbin/getty -L ttyS0 115200 linux

All we need to do now is comment out this line and reboot.

Running automatically on startup

The sole purpose of this device will be to act as an streaming server. This device should be purely “plug and play”, therefore we have to fire all required services right after startup in an automated fashion. We will use: /etc/rc.local  As it says in the comment section, “this file is executed at the end of each multiuser runlevel”. We will add a call to our startup bash script located in /root/scripts/startup.sh that will initiate all necessary services and programs for our streaming server.

startup.sh
#icecast auto started by init.d
#start darkice
/usr/bin/screen -S darkice -d -m /usr/local/bin/darkice

#seems to be required for serial port
/bin/stty -F /dev/ttyS0 19200 time 5 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke
#start serproxy
/usr/bin/screen -S serproxy -d -m /usr/local/bin/serproxy

#start python script
/usr/bin/screen -S ubc780 -d -m python /root/scripts/ubc780.py

#set blue LED on Dreamplug to indicate all services running
echo 1 > /sys/class/leds/guruplug\:green\:wmode/brightness

IceCast & Darkice

Alternatively, these services can be set to run automatically on startup by setting their configuration file in /etc/default

root@dreamplug:~# cat /etc/default/darkice 
# Defaults for darkice initscript
# sourced by /etc/init.d/darkice
# installed at /etc/default/darkice by the maintainer scripts

#
# This is a POSIX shell fragment
#
RUN=yes
# Additional options that are passed to the Daemon.
DAEMON_OPTS=""
USER=root
GROUP=staff

The Icecast / Darkice init scripts did not seem to work with the start/stop/status commands. For some reason the init scripts darkice.pid and icecast2.pid did not  the pid files with the current process IDs. To fix I added the “–make-pidfile” flag to the start-stop-deamon command below

 start-stop-daemon --start --quiet --pidfile $PIDFILE \
 --background --chuid $USER:$GROUP --exec $DAEMON --make-pidfile

and similarly for Icecast

# Defaults for icecast2 initscript
# sourced by /etc/init.d/icecast2
# installed at /etc/default/icecast2 by the maintainer scripts

# This is a POSIX shell fragment

# Full path to the server configuration file
CONFIGFILE="/etc/icecast2/icecast.xml"

# Name or ID of the user and group the daemon should run under
USERID=icecast2
GROUPID=icecast

# Edit /etc/icecast2/icecast.xml and change at least the passwords.
# Change this to true when done to enable the init.d script
ENABLE=true

Open ports on router

The result of the netstat -ntlp command gives us a quick look at what services are running and on which ports. This is no guarantee that they are running correctly, but still a first indication.

nestat -ntlp, showing listening ports and corresponding services

As you can see, a number of ports are used, that need to be port-forwarded correctly through the router in order for our services to be visible and available to the “outside world”.

  • 8000 – IceCast2
  • 2812 – Monit
  • 5331 – Serproxy
  • 10000 – Webmin

You will have to port forward the streaming port 8000 to the same or another external port of your choice in the routers application / port configuration page. Besides the 8000 port you might want to forward also other services.

Port forwarding page on Linksys router. Internal ports can be mapped to any external port of your choice. Beware that this setup shown  above expects the IP of the streaming device to be static on 192.168.1.100

Set static IP on streaming device

By default these devices have DHCP enabled in /etc/network/interfaces configuration file. It would be a good advice to alter these settings and use a static IP like in the example below, were IP 192.168.1.100 is used.

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
 address 192.168.1.100
 netmask 255.255.255.0
 network 192.168.1.0
 broadcast 192.168.1.255
 gateway 192.168.1.254

auto eth1
iface eth1 inet dhcp

Register a domain name on a Dynamic DNS service

Since anyone running a similar setup will most likely be behind a dynamic IP assignment by the Internet provider, we need  a domain name with which the service can be reached. There are a number of dynamic IP registers out there, some of them are free and might require the host-name to be confirmed during regular (monthly) periods. You will have to set the appropriate information in /etc/ddclient.conf configuration file! See section above on ddclient.

Screenshot from the dynamic DNS service provider  showing the current mapping between host-name and dynamic IP

Python script automation

  • looprecorder.py – Voice Activated (VOX) recorder. Records audio that surpasses a minimal threshold. The recordings are saved to an external USB device. I would recommend getting one with a LED indicator, to have visual feedback of whenever a “read/write” is taking place. The recording are saved as raw WAV files. At midnight these files are re-encoded to MP3 files and the process terminates. This script has been added to a daily crontab at 00.00 every night for automatic startup. At the end of the day you end up with a daily recording with the date stamp as the filename.
  • bc780.py – Radio interface. Connects to the serial port of the radio. Activates the “Squelch report” option (QUN command) that sends (asynchronously) a “+” character whenever the squelch on the radio is broken, which means that a reception is being made.

Finetuning…

Run alsamixer to set the microphone levels to an adequate amount around 30% on my system and with the “autogain” set to disabled (press M)

Clients

There are a number of players out there that support streaming audio, but we should prefer the ones that have metadata support so we can see the tuned frequency baked into the stream!
A personal favourite that dates back to the Napster era is Winamp. Enter your server’s URL as such:

http://dnshostname:icecastport/mountpoint
http:/yourserver:8000/live
Winamp’s Open URL (CTRL + L)

Hopefully you should see the player starting to buffer and connecting to the stream successfully.

Winamp: Excellent player with metadata support. Note the tuned channel and frequency displayed!

Listening behind a proxy

If you plan to connect with your client from a corporate environment you will most likely be sitting behind a proxy. You will have to know the proxy IP address and configure this in the client player’s configuration.

winampconf
Configuring the proxy on Winamp

That’s all folks! Enjoy listening to your scanner online!