Abusing Public WiFi Access Point Protocols for Fun and Beer Measurement (Raspberry Pi)

This is a little sub-project of what I’ve been working on recently – a hideously over-engineered Raspberry Pi-based system to measure the amount of beer left in the kegs in my keezer.

Normally I would simply set up a web server on the Pi and have it on the home network, so I could see the levels remotely. The problem is that the routers are all inside the house and the Pi is in the garage, invisible to them all thanks to the 2 external walls between them. I needed some way to read out the beer levels on my phone – after all, walking up to something and looking at the level gauge is so last millennium.

So – Bluetooth or some sort of ad-hoc Wifi thing? I like to re-use stuff I’ve got lying around in drawers, so the solution seemed to be an old WiFi dongle that was gathering dust. And Bluetooth is awful. Setting up a Pi as an access point is fairly well covered on the internets, but this is a bit different in that we don’t want to forward traffic onto our network like an access point – not that it could connect anyway, being out of range. I also didn’t want to install a web server on the Pi. It’s only a Pi 1 model B, so sticking Apache and PHP on it might be asking a bit much – especially when you can do it all with one command and a small BASH script.

So the cunning plan was to take advantage of a feature of public access points – the ones that show you a registration page for you to fill in with fake info.

When you connect to a public WiFi hotspot your device tries to load a page on the internet using non-SSL http. It might be any page (captive.apple.com/ seems to be popular), but it will be a web page that the device knows should exist and if it loads, your device knows the internet is working.

A public access point intercepts the page request and, rather than forwarding it, sends a 30x redirect HTTP response back to the device – basically hijacking the request and spoofing the reply. Your device then loads up the page it has been redirected to and displays it as a sign-in page.

It is this mechanism that I used to show the keg levels on any phone, just by connecting to the Wifi. This is how to do it if you want to do something similar. I’m assuming you SSH on to a Pi connected with an ethernet cable to your network, and you have a Wifi dongle hanging out of its USB port. In all likelihood they will be eth0 and wlan0 respectively, so I’ll use them.

wlan0 is going to use a different range of IP addresses from the ones used by eth0, so edit /etc/dhcpcd.conf to manually assign an IP address to the wlan0 interface. Add this at the bottom (comment out any existing definition for wlan0):

interface wlan0
    static ip_address=192.168.4.1/24
    nohook wpa_supplicant

Next we need to install hostapd to run the hotspot and dnsmasq to sort out assigning IP addresses to devices that connect.

sudo apt-get install hostapd
sudo apt-get install dnsmasq
sudo systemctl stop hostapd
sudo systemctl stop dnsmasq

The second two commands disable the services we just installed so we can edit config files before starting them again.

Create the file /etc/dnsmasq.conf and put this in it:

interface=wlan0      # Use this interface - usually wlan0
dhcp-range=192.168.4.2,192.168.4.20,255.255.255.0,24h

This tells dnsmasq to assign the range 192.168.4.2 – 192.168.4.20 with a netmask of 255.255.255.0 and a lease time of 24 hours. When dnsmasq restarts it will look at this file and load up the config information.

Now to set up hostapd. Create /etc/hostapd/hostapd.conf and put this in it:

interface=wlan0
driver=nl80211
ssid=Your SSID here
hw_mode=g
channel=7
wmm_enabled=0
macaddr_acl=0
ignore_broadcast_ssid=0

It’s pretty obvious what is happening there, other than some of the technical bits; wmm_enabled is something to do with packets (no idea what, though), macaddr_acl tells it to whitelist all connections and ignore_broadcast_ssid tells it to broadcast the SSID – set it to 1 to hide it. There is no WPA password or setup, obviously. Change the SSID to something hilarious.

Now you need to tell hostapd where to find the config file when it starts. Edit /etc/default/hostapd and add (or uncomment and edit) the line:

DAEMON_CONF="/etc/hostapd/hostapd.conf"

We have now set up our access point. Start dnsmasq and hostapd again:

sudo systemctl start hostapd
sudo systemctl start dnsmasq

If there are no errors, your AP should show up in the list of APs on your phone, laptop etc. Try connecting to it – it should connect but you won’t be able to see the internet because there is no forwarding. One thing you can still do however, is connect to SSH on the Pi. You really don’t want any ports other than 80 visible from an unsecured AP. We’ll use iptables to set up a firewall and do the test page hijacking.

sudo iptables -A INPUT -p tcp -i wlan0 --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp -i wlan0 -j DROP
sudo iptables -t nat -A PREROUTING -p tcp -i wlan0 --dport 80 -j DNAT --to-destination 192.168.4.1:80

The first one tells iptables to allow through connections on port 80 (HTTP), the second tells iptables to drop all other TCP connections from wlan0. The third redirects any connection with a destination port 80 (regardless of the IP address) to the Pi at IP address 192.168.4.1, port 80, for our server to handle. If you are a bit confused about how iptables work, this flowchart will either clear things up or make it more confusing. Basically there are 4 tables – filter (default if no -t switch), nat, mangle and raw which each contain “chains” such as INPUT which are the instructions on how to route traffic. It’s a vast subject and I learned just enough to work out the 3 lines above. There are other guides that go into more details.

One thing to do at this point is make it so that the iptables configuration is not lost when the system is rebooted. This command saves it to a file:

sudo iptables-save >/etc/iptables.ipv4.nat

To reload the configuration on boot put this in /etc/rc.local

iptables-restore < /etc/iptables.ipv4.nat

So, moving on to the web server. I’m using socat and a bash script. socat is one of those amazing Linux tools that is impossible to explain to a layperson. “What it does is, it takes data from one place and puts it in another but it’s more complicated than that…” and so on. Best just to tell them it’s the computer equivalent of magic, before their eyes glaze over and they start thinking about feigning an illness in order to escape. We are going to use it to pipe data from an internet port to a script and back again. Incoming text from port 80 is sent to the script on stdin and anything written to stdout gets sent back to the port. It’s easy enough to set up with this command:

sudo socat TCP4-LISTEN:80,reuseaddr,fork EXEC:"/home/your_path_here/server.sh >/dev/null" 2>/dev/null &

Obviously change “your_path_here” to where you are doing all this stuff and put this line in /etc/rc.local if you want it to start automatically on boot. The command tells socat to listen on port 80 and then fork off the script when there is a connection. The script referred to as /home/your_path_here/server.sh is this:

#!/bin/bash

PAGE_NAME="kegs"
FOUND_URL="http://1.1.1.1/$PAGE_NAME"

request=""
while read -r  -t 5 line; do
  if [[ ! -z "${line:-}" && $line == *[^[:cntrl:]]* ]]; then
    if [[ ${line:0:4} == "GET " ]]; then
      request=$(expr "$line" : 'GET /\(.*\) HTTP.*')
    fi
  else
    break
  fi
done

if [[ "$request" == "$PAGE_NAME" ]]; then
  printf "HTTP/1.1 200 OK\n"
  printf "Content-Type: text/html\n\n"
  cat index.html	# Show this as a registration page.
else
  printf "HTTP/1.1 302 Found\n"
  printf "Location: $FOUND_URL\n"
  printf "Content-Type: text/html\n\n"
  printf "Redirect to <a href=\"$FOUND_URL\">$FOUND_URL</a>\n"
fi

That’s pretty dinky for a web server, huh? Don’t forget to change permissions of server.sh with chmod 755 server.sh. Rename PAGE_NAME and FOUND_URL to whatever you want. Note that because we are grabbing all port 80 traffic coming in on wlan0, it doesn’t matter what you put for an IP address – it’ll all go to our server. The first block of code reads the HTTP request coming from the device, which will be saying something along the lines of:

GET / HTTP/1.1
Host: captive.apple.com
Accept: image/gif, image/jpeg, */*
... and so on

The script ignores everything except the GET /… part, from which it extracts the page name, if any. It won’t match (unless the test page is called “/kegs” – unlikely), so it will respond with the redirect code 302, to send the device to “/kegs”. The device sees the redirect, thinks it’s for a registration page and loads 1.1.1.1/kegs. This time the script sees that /kegs has been requested, sends a 200 OK code and the contents of index.html, which the device displays. My beer measurement system generates index.html as a page showing how much is left in each keg.

As a useful tool with which to quickly see the levels of my kegs without any fuss, this is rubbish, quite frankly. But then the whole raspberry-pi-based-keg-measurement thing could be replaced with cheap mechanical bathroom scales, so I might as well go all in on the pointless technology.

Updated 10/6/2020 : Improved the firewall rules.

Taming the PiFM Transmitter (Part 2)

In part one of this guide it became clear that a Raspberry Pi with a 700 mm long wire on pin 7, running a variant of the PiFM software is an easy way to make a nuisance of yourself. We might not be broadcasting kilowatts of power and realistically, you are not going to be knocking planes out of the sky, but the Pi is a dirty old man when it comes to broadcasting and we need to clean up its act.

The obvious way to do that is to put a filter between the Pi’s output and the aerial. If the design considerations and analysis of the filter’s performance don’t interest you, skip to the end for circuit diagrams, construction instruction and purchase info (possibly).

As always, these posts are for educational use only. Do not use your Pi as a transmitter unless it is legal for you to do so, which is highly unlikely. Using a filter will not make it any less illegal for you to use your Pi as a transmitter.  Always brush your teeth before bedtime and be nice to people.

To recap, this is typically the sort of thing that comes out of your Pi when you use it as an FM transmitter:

There’s a lovely spike around the 144 MHz mark, which is the amateur radio 2m band. There are probably not many radio hams near me that like the sort of music I listen to. Come to think of it, some times I’m not sure I do either. In general, it’s a broad splattering of crap all over the spectrum. And the Pi’s transmitted output is just as bad, ho ho ho. Ahem. This is the sort of thing we need:

You might notice R1 there. The GPIO pins are not designed to drive inductive or capacitive loads, so we need to make the filter input a bit more friendly. The easiest way is to put a resistor between the Pi and the filter’s inductor. I’ve tried it and it works, but it does reduce the range of the transmission. If you want to try it without R1, don’t blame me if you fry your Pi. There’s about 5 dB loss with this design, which might be fine for you. For me, it reduced the range just enough that the signal was fading out if I stood in the wrong part of the kitchen. The solution was either to avoid using the fridge or to amplify the output a bit.

I’m not an expert with RF circuits (although I probably know more than you), so I used the interwebs to find a design that would

  • Be cheap
  • Work on a 5V supply
  • Not require any fine tuning
  • Be cheap
  • Be easy to make
  • Not have any expensive components

You can probably tell what my priorities were. This was the prototype:

Those with a keen eye have probably already spotted that it looks shit. Bear in mind that it’s already been bodged around a bit, and it looked worse than that by the time I’d finished experimenting with the poor thing. It is a single stage class C amplifier with a low pass filter on the output. The 2N4427 transistor is old and cheap; I bought 5 from China for about £3. Everything else (apart from the variable capacitors) is bog standard and the coils are easy to wind. The variable capacitors are stupidly expensive – there is about £20 worth of them in that photo, so they had to be replaced with fixed ones that cost pennies.

The end result was this circuit:

Pi Hat Filter – click to enlarge.

It’s cheap, simple and it works quite well. This is the finished hat installed and working:

This is the output with the filter hat on:

Out of band signals are attenuated by at least 20 dB, which means they are 1/100th the power of when it was hatless. There is even a little bit of gain at our broadcast frequency, which also amplifies the in-band harmonics, unfortunately. It’s not exactly BBC quality but it should stop you annoying the neighbours. If you want to get the absolute maximum performance out of the filter, use 5-95pF variable capacitors instead of C7, C8, C13 and C16 and keep tweaking them until it becomes apparent that you aren’t really having any effect.

The design files are here.  If you would be interested in a kit of parts or a ready made hat, leave a note in the comments and I’ll look into it.

I’ll leave you with a comparison of the filtered (orange) Vs. unfiltered (blue) Pi:

Good, eh?

Taming the PiFM Transmitter (Part 1)

One of the million things you can do with a Raspberry Pi is using it as an FM radio transmitter. It is stupidly easy; you just attach a 700 mm long wire to pin 7 and install one of the many variants of the original program which was hacked together at a code club meeting. And now you are a radio pirate. This guide is aimed at those who can do the above but don’t know why it might be a bad idea. If you already know about harmonics or know that they are bad but  don’t care why, you can skip to the next post which is about adding a filter to your Pi.

At this point it is traditional to say that broadcasting without a license is illegal in most countries and doing something like using your Pi to stream internet radio stations to the analogue radio in your kitchen is wrong and makes Eben Upton cry.

One thing you will often hear in discussions about Pi radio is that lots of unwanted harmonics are produced on frequencies other than the one you are broadcasting on. These can interfere with legitimate users of that frequency; for example a passing pilot might not want to hear the Crisp Biscuit Breakbeat remix of Josh Wink’s Higher State of Consciousness instead of the control tower telling her where to land. You might think that anything broadcast from your little Pi won’t be powerful enough to interfere with a professional communications system, and you are very probably right. But what exactly is coming from our Pi’s aerial? This is what we would like to see:

What we would like to see coming out of our Pi. Click for a better view.

Along the X axis are all the frequencies from 50 MHz to 350 MHz. The Y axis shows the level of the signal at that frequency in dB. If you just clicked on the “dB” link and are none the wiser, the upshot is that the dB makes it easy to compare the relative powers of signals. For example, a +3 dB difference is twice the power and a -3 dB difference is a half the power. So +6 dB means the signal is quadruple the power of whatever you are comparing it to – it’s the same as a +3 dB doubling and another +3 dB doubling. As the dBs go up in linear fashion, the corresponding power goes up exponentially: +3 dB, +6 dB, +9 dB corresponds to x 2 power, x 4 power and x 8 power.

The graph shows the main peak of our transmission at 107.3 MHz, at about +11 dB, a harmonic at 214.6 MHz at -25 dB and another at 321.9 MHz at -30 dB. These unwanted harmonics are bad, but their levels are a lot lower than the main broadcast frequency. If the harmonic’s signal level is -36 dB compared to the main one, it means it’s about 4000 times weaker and we don’t really need to worry about it, given that the main signal only goes a hundred metres or so. The other unwanted signal is even lower: -41 dB compared to the main signal so I’m not even going to bother to work out the exact value because it is so small. OK, it’s 12,500 times less than the main signal. That won’t even make it out of the room.

So that’s our ideal transmitter, with a nice strong signal on the frequency we want and weaker signals on the frequencies of the harmonics we don’t. How does this compare to the actual signal from a Pi? Take a look at this little beauty – it is what’s coming out of my my Pi when it’s broadcasting on 107.3 MHz:

Actual output from a Pi. Barf.

It’s spewing crap from 50 MHz to 800 MHz and probably beyond. One of the harmonics is actually more powerful than the frequency we want to transmit on. The signals coming out of that aerial are dirtier than a dog in a field of incontinent cows [todo: change this to something more tasteful]. The neighbours are probably wondering why old skool breakbeat trance music is coming out of their hoover.

It gets worse though. The harmonics coming from the Pi change in number, size and position as you change the frequency. Broadcasting on exactly 100 MHz actually produces a graph somewhat similar to the first one, but drop the frequency by 1 MHz to 99 MHz and you get this:

99 MHz – Craptastic!

Now that is quite pretty, but it did genuinely start making lines go down my monitor and a hum come out of my speakers. God knows what it was doing to the output electronics in the poor Pi.

So, before doing anything else, you need to pick a frequency that won’t make music come out of your granddad’s fillings. The cleanest one is 100 MHz, but where I live there’s already a commercial station there, so that was out for me – my little Pi couldn’t compete with the big boys. You don’t want to pick one that’s close to 100 MHz either because they seem to be the dirtiest. Trial and error, picking the gaps between existing stations, seems to be the way to do it. Ideally, you want a spectrum analyser like the one I used to make the graphs, and surprisingly, you can get the hardware for about £20, and use something like this to turn it into a spectrum analyser. At the very least, you could pick a frequency and see how many times your broadcast appears when you tune your radio up and down. As a general rule, the fewer times the better.

But however carefully you choose your frequency, your Pi will still be broadcasting all over the spectrum and possibly making someone near you very angry. You can improve things by putting a filter on its output, and I can show you how in the next post.

windows-movie-maker.org is a scam

Sorry, that’s much of a punchy title for the first new post in over a year, but the only punching I want to do right now are ones aimed at the scamming gits behind windows-movie-maker.org.

Movie Maker is a nice, easy to use video editor that Wibs had on his old laptop.  So we downloaded it, installed it on his new one and he spent a happy hour knocking up his first movie on the new lappy.  The alarm bells started ringing in the back of my head when it said we needed to buy a registration code in order to save the video.  I didn’t remember the previous version doing that, but we couldn’t remember if we actually bought it or not.  I think the bit of my brain responsible for memory was damaged when I installed the alarm bells.

So a quick search later and I discovered that Windows Movie Maker was released by Microsoft as Freeware, and discontinued in January 2017. Freeware means not asking for money, so what the hell did we have on Wibs’ laptop?  It turns out that we had installed it from windows-movie-maker.org. It looked and acted like Movie Maker, but it wasn’t Movie Maker. Searching for the site name is not reassuring.  At best it’s a scam, at worst it infects your computer with malware.  People have paid for a registration code and received nothing, others have had their computer damaged by it, and others have reported malicious-looking files added.  Luckily we installed it on a fairly new PC, so we didn’t lose much when I “nuked it from orbit” and re-installed Windows.

So, in conclusion and in bold red:

You do not need to pay for Windows Movie Maker.  If it asks for a registration code, it’s a scam and probably downloaded from windows-movie-maker.org, a scam site.  If you have used the scam version, at the very least run a good malware checker like Malwarebytes or better, re-install Windows.

There is a genuine download for Windows Movie Maker which appears to be legit, although I haven’t tried it myself yet. Thanks to John for letting me know.

 

Pirpl – it’s another Pirate Radio PLaylist thing!

Old Radio Station EditedIf you liked the previous Pi-rate Radio Jukebox (and 15 people did!), you won’t want to miss this latest version of it.  It’s basically the same thing, but it runs as a daemon, so you can fire up your favourite tunes using a browser rather than logging in to your Pi to start up scripts.  As usual it’s horribly coded in Bash and features a fuck-ugly interface with no aesthetic considerations whatsoever.  You can insert prettiness yourself if you want to – it’s easy enough because the web pages are done as templates.  All the code is commented to pad it out and make it look more substantial than it is clearly show what is going on.

This one is called Pirpl and is pronounced “Purple” because it seemed like a good idea at the time.  Something to do with Pirate Radio PLaylists or something – it’s all a bit tenuous, quite frankly.  Anyway, the main improvement is that rather than telling it what to play from the command line,  you pick what you want to listen to from a list on a web page.  As before, you can tell it to play all the MP3s in a directory (and all sub-directories) or give it a list of MP3s to play in a file.  It’ll then play them (in a random order if you want), showing the current tune on a web page and allowing you to skip a track or stop playing and go back to the playlist chooser.

Other improvements are:

  • Support for MP3 ID tags in both version 1 and version 2 format.  The old player only recognised version 1 tags.
  • Umm… that’s about it really.  The code is slightly better in places, I suppose.  Still the playlist choosing thing is good, isn’t it?

Quick start

pirpl
Nice clean lines. What is not to like?

Want to get going already?  This is the tarred archive (20.8 kB)

Download the archive, untar it, edit the “pirpl_conf” file (you’ll see why in the file) and add playlist information to the “pirpl_playlist.conf” (you’ll see how in the file).  Before you can start it up, you need to make sure that the following packages are installed on your Pi:  netcat, sox, id3v2.  If one or more isn’t then, install any missing ones with

sudo apt-get install netcat sox id3v2

The program that does the transmitting needs to run as root, so setuid  that bad boy up with:

sudo chown root:root pifm
sudo chmod 4755 pifm

Before you can oscillate any electromagnetic fields, you’ll need to make an aerial for your Pi.  Instructions are in first paragraph of the drivel for pirbj.

Once you are sorted, start the whole lot up with the command:

./pirpl.sh pirpl_conf

To stop it press CTRL-C.

The gruesome details

There are quite a few files that make up pirpl.  This is how they work.

pirpl.sh

This is the main program file.  Have a look at it if you want to gaze in wonder at the insane beauty of Bash, but there is no need to edit it.  All the configuration stuff is now in…

pirpl_conf

Various settings for things like the names of files, the transmitter frequency and where you installed pirpl.  You probably want to change the transmitter frequency to somewhere empty on your radio’s dial.  You will also need to change PIFM_BASE to the directory where you untarred the files.  The web server port should not be accessible to the outside world.  Other than that, it’s probably best to leave everything else as it is unless you really like reading error messages.

pirpl_playlist.conf

This is where you tell pirpl all about your music.  Each line has the path to the playlist or directory containing MP3s, the displayed name of the playlist, and whether to shuffle it.  I’ve left all my playlists in as examples.  Actually, I forgot to delete them and now I can’t be bothered to take them out.  Sorry.  If you are using a playlist rather than a directory, the format is one path to an MP3 per line.

pirpl_playlist_template.html

Your browser will show this as a web page so open that link, right click and choose “View page source” to see what is in it.  You have probably worked out for yourself that this is a template file for showing the available playlists, as defined in pirpl_playlist.conf.  The bits in “@@”s are replaced with the information about playlists.  I’m sure you can work out what’s going on in that file.

pirpl_template.html

This is the template for showing information about the track that is playing.  It’s the usual stark functionality you get from me, simply because it works and I can’t be bothered to try and make it look nice.

pirpl_server.sh

This is the script that does the web server.  It doesn’t do much; it just outputs a file to the browser and filters commands out of the text sent by the browser, storing any it finds in a file which is picked up by pirpl.sh.

pifm and source/pifm.c

The program that does the transmitting.  It’s a barely modified version of this one and the source is included if you want to have a look and compile it yourself.

startwrapper.sh

The best way to start Pirpl is as a service, when the Pi boots up.  You don’t want to run it as root, so the easiest way to start it as a normal user is to put a command similar to this in your /etc/rc.local file:

sudo -u naich /home/naich/pirpl/startwrapper.sh

You could use sudo to start Pirpl directly but you end up with sudo hanging around like a bad smell in your process list.

In conclusion

Using this program without the proper license is probably illegal where you are, so don’t use it ever.

Friendly wave!

road rage 620It’s been a while since I’ve had a good rant about the shower of bastards I encounter on the roads.  I’m not commuting through Cambridge itself any more, so I don’t encounter so many of them.  Also, although my route is over twice as long now, it uses quite a few cycle paths of varying lethality, ranging from “sort of OK” to “wheel-fucking argh! clang oh shit I think I’ll stay on the road”. Of course, most of the people I encounter on the roads are boring sods who aren’t even bothered with me being there and show respect by passing safely.  Yawn.  How can I wake up in the mornings without the surge of adrenaline from a near miss?  Some even pass on helpful advice, like the young man who veered towards me on his moped and shouted above the noise of his “bee farting in a tin can”-type exhaust that gwargle obbly wobbly.  I asked a qualified aromatherapist about this later and discovered that he was correct.  I’ll not bore you with the details.

But there are still a few hilarious encounters with people who want to liven up my day by giving me a nice scare, shouting out of the window or expressing their complex thoughts about road safety, the role of the cyclist in the ever-more frenetic highway ecosystem and the merits of the primary and secondary road positions, by going “beep”.  So I’ve tried a few different responses.

1.  Middle finger salute.  Instant gratification on my part, but the driver usually responds in kind, causing gratification for him/her too.  I don’t want them to feel better as well.  The last time I tried this, the scrote who had just carved me up waved his arms a bit and then slowed down further up the road, presumably to have another go at running me over when I caught up.  Funnily enough he had to give it up when a white van roared up behind him and, with military precision, tailgated him at 1 millimetre’s distance until he sped up.  The irony of his sudden change of place in the vehicular pecking order was probably lost on him.

2.  Stopping for a chat.  Fun, but it’s quite rare for anyone to actually stop when I make pointing motions for them to pull over.  It’s important to be friendly and cheerful to put them off their guard, because they’ll want a good shouting match.  The only time I successfully had a chat, she explained that the reason she almost took my right elbow off and beeped was because my riding position meant she couldn’t overtake when there was a car going the other way.  I pointed out that if she couldn’t overtake when there was a car going the other way, then maybe she shouldn’t overtake when there was a car going the other way.  She replied that I was lucky her boyfriend wasn’t there.  She didn’t explain why.  Maybe he’s really ugly and smells like rotting turnips or something?

3.  Smiling and waving.  I’ve only tried this once, but it worked quite well.  I didn’t get the instant relief of a nice rage hit but, on the other hand, the beeper got no gratification either.  The complete failure to get her message across seemed to send her into spasms.  “Beep!”  Big cheery wave from me.  Frantic hand signals from the beeper as she watched me in her mirror and weaved around the road slightly.  Another cheery wave and a nice grin from me, and she disappeared from sight, still weaving around all over the shop.

Or I could do what a friend of mine has done, and fit a car horn to my bike so I can beep back.

Pi-rate Radio Jukebox

p1070168Note: there is an update to this post.

There is a nice hack for a Raspberry Pi where you can turn it into an FM transmitter.  While this is illegal in most countries, the range is quite limited so it’s fairly unlikely you’ll go to prison. The only hardware needed is your Raspberry Pi and a piece of wire attached to pin 7 (GPIO 4) of the GPIO connector.  The length of the wire depends on the frequency you are transmitting on – roughly speaking, it should be 299/(frequency x 4) metres long.  So 103 MHz is 725 mm.  Or if you are using inches, 299/(frequency x 0.1016) inches.

It’s very easy to transmit internet radio using just one line of Bash but if, like me, you have a few thousand MP3s , there’s no quick and dirty way to pump them out to the transmitter.

Until now.  Behold the PIrate Radio Juke Box (pirjb). If you can think of a better name for it, please leave a comment.  A couple of Bash scripts, a minor alteration to the pifm code and a reckless disregard for radio licensing regulations is all that is needed to listen to your collection on any FM radio.   You can repeat and shuffle with either a playlist of MP3s in a file or point it to the directory the MP3s live in and it’ll scan them and make its own playlist.

Also included is a web server to show you the currently playing track.  Using your browser, you can skip to the next track or shut everything down and turn the transmitter off.  Note that you can’t turn it back on with the web interface yet.  That’s the next thing on the to do list.  You can get to the page by going to http://your_pi_address:8080/  The “8080” is set in the pirjb.sh file, at the top.

Note that I do not condone or encourage the use of transmitting equipment without the proper license.  This article is presented purely as an exercise in theoretical programming.  Your statutory rights are not affected.  Your home may be at risk if you set fire to the curtains.

Setting up

You need to have the following packages installed: sox, netcat, mp3info.  Use

sudo apt-get install sox netcat mp3info

to install them.

Copy the pirjb archive to an empty directory on your Pi and extract the files with

tar zxf pirjb.tgz

You need to edit pirjb.sh.  The top few lines are where things like the transmission frequency, path to the scripts and the port for the web server are defined.  There is also a line for the compander settings for sox in order to have an AGC.  If you didn’t understand that last sentence, don’t change that line.  I’ve also included the source for the pifm binary included in the archive.  There is a very minor change to it from this one – calling it with no parameters turns off the transmitter.  Please do compile it and use it instead of the binary I’ve put in the archive.  You shouldn’t really be running binaries from random geezers on the interwebs anyway.  And I am sometimes quite random.

You need to make pifm run as root using setuid in order for the transmitter to work.  Do this with:

sudo chown root:root pifm
sudo chmod 4755 pifm

To run it use:

pirjb.sh -d <directory name>  or
pirjb.sh -p <playlist>

Switches are -s to shuffle the track order, -r to repeat the playlist indefinitely.  The playlist file should have the full path of each mp3 you want to play per line, i.e.

/home/naich/music/Wombles Christmas Special/01 Wombling Christmas.mp3
/home/naich/music/Napalm Death/Scum/Human Garbage.mp3
… and so on.

Have fun playing with it and do not use it because it is illegal to do so.

Files included in the archive:

  • pifm : The transmitter binary
  • pirjb.sh : The jukebox script.  Edit the first few lines for your system.
  • pirjb_webserver.sh : The webserver script.  No need to edit it.
  • pirjb_template.html : The template for the web server page.  See pirjb_webserver.sh for information about using it.  Or just look at the file itself and have a guess.  It’s not hard to see what’s going on.
  • source/pifm.c : The source for pifm.  Compile with g++ -O3 -o pifm pifm.c then copy over the top of pifm.  Don’t forget to chown and chmod the compiled program.

Bash Brackets

Handy guide to bash brackets, swiped from Stackoverflow.

Brackets

if [ CONDITION ]    Test construct  
if [[ CONDITION ]]  Extended test construct  
Array[1]=element1   Array initialization  
[a-z]               Range of characters within a Regular Expression

Curly Brackets

${variable}                             Parameter substitution  
${!variable}                            Indirect variable reference  
{ command1; command2; . . . commandN; } Block of code  
{string1,string2,string3,...}           Brace expansion  
{a..z}                                  Extended brace expansion  
{}                                      Text replacement, after find and xargs

Parentheses

( command1; command2 )             Command group executed within a subshell  
Array=(element1 element2 element3) Array initialization  
result=$(COMMAND)                  Command substitution, new style  
>(COMMAND)                         Process substitution  
<(COMMAND)                         Process substitution

Double Parentheses

(( var = 78 ))            Integer arithmetic   
var=$(( 20 + 5 ))         Integer arithmetic, with variable assignment   
(( var++ ))               C-style variable increment   
(( var-- ))               C-style variable decrement   
(( var0 = var1<98?9:21 )) C-style trinary operation

This might be a bit of a niche subject, but I’m leaving it here for my own use.

Everybody needs good neighbours

Following a repossession and a long vacancy, the house next door has a new owner, who is doing it up. We share a drive and I bumped into him as he was unloading decorating stuff from his car. I’m not good at chit chat. “Hello” I said. “Hello” he said. “You own the house now?” I said. “Yes” he said. That was the point I realised I had completely run out of conversation. He stared with increasing panic at me while I frowned furiously, trying to think of something else to say. This continued for a while. My brain had seized up completely, locked at 100% CPU, trying to think of anything to say that wasn’t just fucking insane. Meanwhile, my facial muscles stayed the same in the absence of any further direction from further up the head. In the end he dived inside the house to escape the steady but vicious frowning that was being pointed in his direction.

The next day I was brewing up some beer in the garage with the door open. I was at the stage where you boil it with the hops, and I had a nice rolling boil going in my large stainless boiling pot. My boiler has various wires coming out for heaters, thermometers and the like, along with taps and attachments for chilling the liquid once the boil is done. I had my head immersed in the aromatic steam when I spied my neighbour walking from his house to his car. He spotted me and looked puzzled, so I thought I’d try to be friendly again. I was trying out a large friendly grin when it occurred to me that it might look a little odd that I was grinning at him with my head immersed in steam coming from some weird contraption with wires and pipes coming out of it. I couldn’t help it when my grin turned into a bit of a giggle, which must have added to whatever effect my steamy grinning was having on him because his quizzical expression turned to one of alarm and he almost ran to his car.

The day after that wasn’t any better for neighbourly relations. I was leaving for work in the car, just as his car appeared at the end of the drive, turning in from the main road. I stopped and started waving my arms about a bit, mouthing words to convey the message that it was perfectly OK for him to continue down the drive and I would reverse back into my parking space so he could get off the main road safely because I’m nice like that and not a dangerous maniac. I’m guessing that from his point of view, the dangerous maniac with the weird laboratory in his garage was annoyed that he was coming down the drive, getting shouty and angry. He reversed back on to the road at high speed in what was, quite frankly, a shockingly dangerous manoeuvre. I tried to catch his eye as we passed but he seemed to be hiding behind the steering wheel.

I haven’t seen him since and I’m not quite sure how to convince him that I am almost normal and really not that dangerous.