UP | HOME

Raspberry Pi Mobile Internet Router

Introduction

Living alternately in an off-grid home in the woods and a campervan, a reliable Internet connection is hard to come by. For a while, my partner and I we got along by using a combination of public Wifi and the Hotspot functions of our smartphones. However, this is tedious in the long run, so I decided to turn a Raspberry Pi 2 Model B (that I already had) into a mobile router. What I like about the Pi is that it draws its power through Micro-USB, which allows us to easily run it in our off-grid home as well as the van straight from the 12 V battery system with a simple car USB adapter.

I mainly followed the Instructable tutorials by BigCowPi and Deviprasath with a few extra solutions here and there.

I purchased a USB Wifi dongle (as the Raspberry Pi 2 Model B, unlike the Pi 3, doesn’t have built-in Wifi) as well as a 3G GSM USB modem to hold a SIM card. I made sure to buy device that were recommended as Raspbian-compatible. The Wifi dongle is an Edimax EW-7811UN (“ideal for Raspberry Pi”), and the 3G modem is a Huawei E173.

SSH like MacGyver

You will probably be able to skip this step unless you’re utterly unprepared as I was. If you have either an ethernet cable (and your Pi has a working installation of Raspbian with SSH enabled) or a screen and a keyboard, you can go directly to the next section.

The first problem I ran into was that while I had previously installed the Raspbian distribution on the Raspberry Pi, I was unable to log into the device. I had a keyboard and an HDMI cable, but no screen. Neither did I have an ethernet cable or even the adapter needed for my MacBook Air. When trying to find out how to use a laptop as an external screen (impossible, apparently), I learned that fortunately, one can log into the Raspberry Pi via SSH over a USB connection from an Android phone with a terminal emulator by turning one of the Pi’s USB ports into an ethernet port and assigning a static IP to it. At least in theory – in practice, this requires editing the file /etc/network/interfaces, which in turn requires access to the Raspberry Pi, right? So it seems I was stuck.

Then it hit me that I might be able to edit the filesystem on the Raspberry Pi directly on the laptop. Not out of the box of course, since Apple doesn’t provide drivers to access Linux filesystems, but with OSXFuse maybe? There is a fork of the Fuse-ext2 project that worked for me so I could edit /etc/network/interfaces as follows:

allow-hotplug usb0
auto usb0
iface usb0 inet static
        address 192.168.42.42
        netmask 255.255.255.0
        network 192.168.42.0
        broadcast 192.168.42.255

After rebooting the Raspberry Pi and connecting my Android phone to it through this special USB port, I was able to log in via SSH (the default password of Raspbian, in case you never changed it, is raspberry, by the way):

$ ssh pi@192.168.42.42

Now I was able to use my phone’s Internet connection by adding a route as explained in the above link:

$ sudo route add default gw 192.168.42.129 usb0

(If needed, find the phone’s IP address using arp -a.) From this point on, the Pi was connected to the Internet through the phone. But we wanted to have it the other way around, so keep reading.

Setting up Wifi

The next challenge was to setup the Wifi. I chose to get this running first in order to be able to log into the Pi from my laptop. The idea is to use a USB Wifi dongle in Access Point mode. It turned out that the Wifi dongle I picked worked out of the box – when used “normally”. But to get Access Point mode to work, there was a little intricacy: I had to compile patched drivers.

Fortunately, the entire procedure is rather straightforward:

$ wget https://github.com/jenssegers/RTL8188-hostapd/archive/v2.0.tar.gz
tar -zxvf v2.0.tar.gz
$ cd RTL8188-hostapd-2.0/hostapd
$ make && sudo make install

From then on, it worked like a charm. I edited the configuration file /etc/hostapd/hostapd.conf as follows:

# Basic configuration

interface=wlan0
ssid=popcorn
channel=1
#bridge=br0

# WPA and WPA2 configuration

macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=3
wpa_passphrase=SUPERSECRETPASSWORD
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

# Hardware configuration

driver=rtl871xdrv
ieee80211n=1
hw_mode=g
device_name=RTL8192CU
manufacturer=Realtek

I now edited back /etc/network/interfaces by undoing the changes made above and editing eth0 and wlan0, as well as adding a hostapd entry. The file now read as follows:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.0.1
netmask 255.255.255.0

auto wlan0
iface wlan0 inet static
address 192.168.1.1
netmask 255.255.255.0

hostapd /etc/hostapd/hostapd.conf

I completed the configuration of the Wifi access point by adding DHCP, appending the following lines to /etc/dnsmasq.conf:

# RPI ROUTER
domain-needed
bogus-priv
interface=eth0
dhcp-range=192.168.0.1,192.168.0.100,12h
interface=wlan0
dhcp-range=192.168.1.1,192.168.1.100,24h

At this point, I was able to disconnect the phone and connect to the Wifi served by the Raspbery Pi from my laptop by joining the network popcorn and issuing:

$ ssh pi@192.168.1.1

Setting up the 3G modem

For the remaining part of this project, I needed a bunch of packages, so I went ahead and installed them right away:

$ sudo apt-get install iptables dnsmasq ppp wvdial usb-modeswitch iw

I did, as expected run into problems with the modem’s data partition which would prevent the modem from being recognized. Different devices require different values in /etc/usb_modeswitch.conf; what worked for me was:

DefaultVendor=0x12d1
DefaultProduct=0x14d1
TargetVendor=0x12d1
TargetProductList=14c9
MessageContent="55534243123456780000000000000011062000000100000000000000000000"
CheckSuccess=20

For the actual 3G connection, there are various options involving scripts to be found, but I chose a simple way using wvdial. I edited /etc/wvdial.conf to match my carrier’s requirements:

[Dialer Defaults]
Modem = /dev/ttyUSB0
Phone = *99#
Username = eplus
Password = gprs
Init3 = AT+CGDCONT=1,"IP","internet.eplus.de","0.0.0.0"
ISDN = 0
Auto Reconnect = on
Stupid Mode= 1
Idle Seconds= 0
Auto DNS = on

and added the following to /etc/network/interfaces:

iface ppp0 inet wvdial

(Unfortunately, auto ppp0 didn’t work here because it would cause wvdial to run on boot before the modem hardware was ready. My workaround is explained below.)

To set up NAT, I edited /etc/sysctl.conf by uncommenting the line

net.ipv4.ip_forward=1

Then I ran

$ sudo iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
$ sudo iptables-save > /etc/iptables.ipv4.nat

and added to the file /etc/network/interfaces the following line:

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

Getting it ready on boot

Unfortunately, I needed to manually have the Pi establish the 3G connection, having to wait for the modem to be ready after boot. (The network devices seem to be brought up before the USB hardware is ready.) I experimented with udev to listen for the device to show up but ultimately didn’t succeed. Instead, I wrote a simple shell script /usr/local/bin/ppp0up.sh that just sleeps 20 seconds before bringing the device up:

#!/bin/sh -e
sleep 20
/sbin/ifup ppp0

and added a line to /etc/rc.local (run on boot):

/usr/local/bin/ppp0up.sh &

This runs my above-mentioned script in the background, so it doesn’t block the boot process. When the internet comes up, the 3G modem will signal it by lighting up its LED in green (EDGE) or bright blue (3G).

The magical memory stick

Now that the system automatically goes online on boot, there is only one problem: How can I shut the Pi down, given there is no button? I don’t want to always open an SSH connection, and I can’t afford to keep the Pi running 24/7 (even though its power consumption is little, it does strain the batteries). People have added shutdown buttons to their Pi computers via the GPIO pins, but that was a little too much for me. Instead, I repurposed an old memory stick by adding a udev rule that would cause the Pi to shut down as soon as the stick is plugged in!

I used lsusb to find vendor and product IDs of the memory stick and added a file /etc/udev/rules.d/11-shutdown.rules with the following content

ACTION=="add", ATTR{idVendor}=="13fe", ATTR{idProduct}=="1f00", RUN+="/sbin/halt"

It usually only takes a few seconds for the system to come to a halt. Happy days!

Addendum: Solving the power problem

The tutorial by BigCowPi mentions the fact that the Raspberry Pi might struggle to provide the power for a 3G modem and a Wifi dongle. I did in fact experience occasional problems where the Pi would (seemingly randomly) reboot. It turned out that the devices were indeed drawing too much power. Fortunately, this is a restriction that can be lifted by changing a configuration setting. In the file /boot/config.txt, adding the line

max_usb_current=1

will provide 1200mA to all USB ports combined, as opposed to the default 600mA. I have not experienced a power shortage since.