Tech!

Kplex Home
Examples
top border

Raspberry Pi NMEA Wifi Multiplexer

Pi Access Point

This page describes how to use a Raspberry Pi to build a wireless access point which also acts as an NMEA-0183 router. I stress that what is described here is not necessarily the ideal way to do it. I've put this page up at the request of others as a starting point. Take some ideas from here and improve on them. If you search for "raspberry pi access point" you will find other ideas.

Some people will be wanting to build an access point which functions purely as an NMEA-0183 to wifi bridge, like some of the commercial offerings. Others will want to combine that functionality with a shared Internet connection. This page will start by describing how to use the pi to build an access point for an isolated network not connected to any other network. Later sections (not yet written) will develop the project, adding hardware (a GPS connected to the pi's console port) and an additional network connection to allow sharing a wifi or 3G connection.

Do be aware that in some cases open source linux drivers are written with incomplete information regarding the closed hardware they need to support. Although others will disagree, my experience with linux wireless over the past decade or so has been that it isn't always consistent or reliable. It goes without saying that this project is not recommended for safety critical systems. I have experienced numerous USB-related lockups when experimenting with the pi as an nmea server and access point.

Assumed Knowledge

Basic knowledge of Linux including use of a text editor is assumed. There is a wealth of information available elsewhere on getting started with the Raspberry Pi that need not be replicated here. Different types of hardware (specifically, different wifi dongles) may require downloading and installing of firmware in order to get working. Because of the variety of different dongles that might be used it is not possible to give step by step instructions.

Required Hardware

Raspberry Pi

I was originally using one of the first generation model Bs with 256MB memory. The memory and processing power are fine for this application but I found the USB bus could be flaky with two wireless adapters connected. This was not a simple power problem as the same issue occurred with a powered hub. Not a problem when only using the pi for an access point but became an issue when also using it as a router to connect to the Internet. Reports from others suggest the B+ improved on this situation and my current Pi v2 is working fine.

SD card

For the Pi's OS. 4GB is sufficient, but 8 or more gives you room to add more software or store more logged data. Note that the newer Pis use a micro SD card.

Power supply

You want to convert the boat's 12v power supply to 5v and provide it to the pi via a micro usb. The easiest option is to use a phone charger designed for a lighter socket. I found a converter with a micro usb connector on one side and 1m of power cable on the other. Either solution should be less than €5 on ebay.

USB wifi dongle which supports master mode

This is the hard part. When acting as an access point, your wifi device operates in what is known as "master mode" (or "AP" mode). Not all devices or their software drivers support this mode. Support for this mode in Linux depends on the device's chipset (ie the electronics inside the device). Unfortunately manufacturers sometimes change the chipset they use in a device without changing the name of their product. You may read in someone's blog post that a particular dongle supports master mode on Linux, go out and buy the "same" thing only to discover you've bought the New! Improved! version with a different chipset which doesn't even work on Linux. The best way to select a dongle is to borrow someone else's, try it, and if it works, don't give it back. Offer to buy them another newer one if you are honest. Alternatively for any device you are thinking about buying, try and find out what chipset it uses then attempt to determine whether that chipset's driver supports master mode under Linux. A summary list of driver capabilities is available on the Linux Wireless web site, although this is not always up to date and accurate. Worst case, be prepared to give several of your friends wifi dongles as birthday presents this year.

I'm currently using an old D-Link DWA-110 (RaLink RT2571W chipset). It's an 802.11g device which is plenty fast enough for boat data, although may not be your best option if you want to push high definition video about.

UPDATE: For my latest re-work of this project I used an Edimax EW-7811un adapter which is commonly sold for use with the Raspberry Pi. This uses the RTL8188CUS chipset which at time of writing requires a custom version of hostapd. The software can be downloaded from the realtek website. I compiled and installed a replacement hostapd, added the declaration:

DAEMON_SBIN=/usr/local/bin/hostapd
to /etc/default/hostapd in order to reference the custom binary, then replaced:
driver=nl80211
with
driver=rtl871xdrv
ieee80211n=1
wmm_enabled=1
I will updated this document with more detail at a later date.

Serial to USB converter(s)

The easiest way to get NMEA-0183 data into your pi is via USB. If the device you want to hook up to the pi outputs NMEA-0183 over USB, happy days. If not you will need a serial to usb adapter. Ideally this should be opto-isolated, but the cost of such adapters tends to be more than replacing the pi several times over in the unlikely event of it being blown up by a power surge. If your NMEA-0183 device outputs data over an RS232 adapter, use an RS232 to serial adapter (~€13 delivered from ebay). If it is compliant with a version of NMEA-0183 prior to v2, use an rs232 to serial adapter. Older equipment and cheap GPS units fall into this category. The device's TX should be connected to the adapter's RX, RX to TX, GND to GND. More modern devices (NMEA-0183 v2 upwards) use RS 422, a differential protocol. You can buy rs422 to usb adapters, but these far harder to come by and generally more expensive than your average RS232 to USB adapters. For input only, many people will just use an RS232 to usb adapter, connecting TX+ to RX on the adapter and GND to GND. Tollerances are such that this will generally work although it is not guaranteed.

The pi only has two USB ports. If you use one for the wifi dongle that leaves you with one. In order to connect more than one serial device via usb we can use a dual serial-to-usb converter, or we can connect a usb hub to the pi, and connect other serial-to-usb adapters to that.

Later we'll look at the alternative method of getting data into the pi via the serial i/o pins normally used for the pi's serial console.

Software

We will be using:

hostapd and dhcpd are most easily installed with apt-get once the pi is up and running. Dhcpd is probably not the best choice of dhcp server: It is a full-fat enterprise-ready piece of software that is undoubtedly overkill for your purposes, but it's what I have used for many years and am familiar with.

Initial Setup

This section may be expanded but for now, follow the Instructions on the Pi foundation's web site to get the pi running a basic OS. For the rest of this guide we're going to be working with the command line.

It is critical that you use an OS image which includes up to date firmware. Issues existed with USB handling code which could cause USB hangs when some serial to USB devices were opened. If your firmware is older than April 2013 and you experience such a problem, either use a more up to date image or upgrade the pi's firware. A popular way of doing that is with rpi-update.

Hardware Configuration

For now we're going to assume you are only connecting one NMEA-0183 connection which carries combined AIS and other data at 38400 baud. After the initial setup described above, plug in your wireless dongle to one USB port and plug in the serial to USB converter to the other. If you're going to use several serial to USB converters, you'll need to use a USB hub.

At this point it pays to check that the wireless dongle really is the device you think it is. Here's the output of the "lsusb" command on my pi:

Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 
Bus 001 Device 004: ID 07d1:3c07 D-Link System DWA-110 Wireless G Adapter(rev.A1) [Ralink RT2571W]
Bus 001 Device 005: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
The wireless dongle is obvious. If we have any questions about it, Internet searches on the chipset ("Ralink RT2571W") or vendor and product id ("07d1:3c07") are often more helpful than searches on the product name: Often several different manufacturers will base their products on the same underlying electronics, and linux may treat them all the same.

Many types of wireless dongle require binary firmware to be loaded on them. Fortunately some of the more common firmwares are already available in the raspbian distribution (in the /lib/firmware directory) and others are available in packages which can be downloaded using normal dpkg tools. If your device doesn't give you a wireless interface, and error messages in your system log indicate a missing firmware file, check if there is a package available before finding instructions on the web for hacking the firmware out of Windows drivers.

Software Configuration

If you're ultimately going to use your pi on a boat without an Internet connection, set it up beforehand somewhere where you do have an Internet connection.

Installing Software

Our first task is to install all the additional software we're going to need. If your installation procedure involved a software update you don't need this next step, otherwise update your apt cache with "apt-get update" then update you software with "apt-cache upgrade".

Next install hostapd...

apt-get install hostapd
...and dhcpd...
apt-get install isc-dhcp-server
Now follow the instructions for obtaining and installing kplex here. Don't worry about configuring it yet.

Configuring hostapd

My /etc/hostapd/hostapd.conf looks like this:

interface=wlan0
driver=nl80211
ssid=NMEA0183
channel=1
country_code=UK
ieee80211d=1
hw_mode=g
auth_algs=1
wpa=2
wpa_passphrase=changeme!
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
Do take some time to read what these settings mean. I've stripped out the comments for brevity but the original prototype (with all comments present) is here. You will minimally have to change the SSID setting to some string of 32 characters or less (31 or less in some implementations) which you like, and the passphrase to some string between 8 and 63 characters long. Change the country code according to your location, and if your wifi dongle doesn't use the mac80211 driver, you may need to change the "driver" line.

To check if your device uses mac80211, type

lsmod | grep mac80211
If there is no output, you will need to work out which driver to use, but if you see some output with "mac80211" somewhere in the left hand column, you're good to go. Here's what I see from the above command on my pi:
mac80211              273413  2 rt2x00lib,rt2x00usb
cfg80211              184163  2 mac80211,rt2x00lib
In some distributions you may need to tell startup scripts where to find the configuration file. This can be done by setting the DAEMON_CONF variable, either in /etc/default/hostapd or the startup script itself. If setting it in the startup script simply append "/etc/hostapd/hostapd.conf" to "DAEMON_CONF=":
DAEMON_CONF=/etc/hostapd/hostapd.conf

dhcpd

Here is a minimal /etc/dhcp/dhcpd.conf for a closed network (i.e. no gateway to the outside world) with no DNS.

ddns-update-style none;

default-lease-time 600;
max-lease-time 7200;

authoritative;

log-facility local7;

subnet 192.168.129.0 netmask 255.255.255.0 {
        range 192.168.129.129 192.168.129.191;
}
You can use any of the private network address spaces specified in RFC 1918. Here we are using 192.168.129.0/24 and allowing our dhcp server to allocate from a pool of 62 address in that range. Later we'll see how to modify this to enable us to link up with a connection to the outside world.

kplex

You can do a lot with kplex but for now we are going to do something very simple: Plug in a serial to usb adaptor with the serial end attached to a 38400 bps (such as would be used for a connection carrying AIS and possibly other data) NMEA-0183 feed and create a tcp server which will allow us to connect to it from a wireless application. For the details of what kplex can do (including broadcasting data over UDP) the instructions are here but for now here's our basic /etc/kplex.conf, which essentially just requires uncommenting the configuration in the example that was installed with the .deb.

[serial]
filename=/dev/ttyUSB0
direction=both
baud=38400
[tcp]
mode=server
port=10110
direction=both
If your NMEA feed is 4800 baud, change the "baud=" directive accordingly.

Iniialisation Script

We could start any of the software we've just configured automatically at boot time independently of the other services which start. However we may want to control the "access point" functionality as a unit: hostapd, dhcpd and (when we add it later) BIND. To achieve this, let's creat a trivial script and call it /usr/local/bin/apctl. We'll develop this script further later.

#!/bin/bash
fname=${0##*/}

usage() {
        echo "Usage: $fname start|stop|restart" >&2
        exit 1
}

do_start() {
        /etc/init.d/hostapd start
        /etc/init.d/isc-dhcp-server start
        /etc/init.d/kplex start
}

do_stop() {
        /etc/init.d/kplex stop
        /etc/init.d/isc-dhcp-server stop
        /etc/init.d/hostapd stop
}       


if (( $# == 1)) ; then
        cmd=$1
else
        if [[ $fname == start* ]]; then
                cmd=start
        elif [[ $fname == stop* ]]; then
                cmd=stop
        else
                usage
        fi
fi

case $cmd in
start)
        do_start
        ;;
stop)
        do_stop
        ;;
restart)
        do_start
        do_stop
        ;;
*)
        usage
esac

exit $?
Make it executable:
chmod 755 /usr/local/bin/apctl
In /usr/local/bin create two links to this file:
cd /usr/local/bin
sudo ln apctl startap
sudo ln apctl stopap
Now let's configure /etc/network/interfaces:
auto lo
iface lo inet loopback

allow-hotplug wlan0
iface wlan0 inet static
        address 192.168.129.1
        netmask 255.255.255.0
        post-up /usr/local/bin/startap
        pre-down /usr/local/bin/stopap

Here we've assigned the address 192.168.129.1 to our wireless interface. When logging in to the pi over ssh from another computer, this is the address we can go to. More importantly, this is the address we will use as the server for our wireless NMEA-0183 apps to connect to.

Firewall Rules

For our first cut, isolated from the Internet, we won't install any firewall rules. Out wireless network should be protected by WPA2 with only clients into which you have entered the passphrase should be able to connect. Ignoring firewall rules avoids us having to discuss variations in rules to accommodate different configurations of kplex. We will revist this when we discuss connecting the network to the Internet.

Disable Unnecessary Services

There are two good reasons to disable services you aren't using.

  1. Security: Any running program is a potential risk. Possibly a very small risk, but if you don't need it, why have it?
  2. Performance: Any running program you don't need is a waste of resources

Misc Configuration

If you're not using IPv6, you might as well disable it. If you have a file /etc/modprobe.d/ipv6.conf, ensure the following line is in it:

alias net-pf-10 off
If you don't, or there isn't, make a file of that name containing the line above. Later we'll discuss making proper use of IPv6 on your boat network.

Firing it up

Everything should start cleanly on boot. You should be able to:

  • See the SSID you specified in hostapd.conf in your list of available networks on another wireless device (e.g. ipad)
  • Connect to the access point using the passphrase you specified and obtain an IP address
  • Connect an application which uses NMEA-0183-over TCP by telling it to use the server at:
    Address: 192.168.129.1
    Port: 10110
    

Next Steps

If there is no link associated with the list items below, that page hasn't been written yet and is "Coming Soon..."

  • Using the Pi's "Serial Port" for an NMEA-0183 connection
  • Adding an Internet connection
  • IPv6 connectivity

bottom border