Introduction
This story explains how to setup a LoRa gateway that is connected to The Things Network through a 4G mobile data network, which is extremely useful to carry on workshops or IoT demonstrations even in the absence of WiFi/Ethernet connection.
Context
This story comes from my job at WSL. WSL is a Startup Advisory Service that is active in the Walloon region of Belgium. WSL has the mission to coach persons or companies with entrepreneurial projects in areas related to engineering sciences. Given the fact that Internet of Things (IoT) is increasingly getting more and more importance to our digital economy, WSL wishes to stimulate the emergence of a strong dynamics related to IoT and data science within Wallonia.
According to this vision, WSL periodically schedules experimentation workshops (nicknamed "Atom-IT sessions") about IoT throughout Wallonia. These wandering sessions take the form of a 3-hours workshop and are the occasion for students, researchers, companies and entrepreneurs to get their hands dirty with IoT technologies for the first time.
As a public entity, WSL wishes to remain as agnostic as possible wrt. the underlying IoT network infrastructure. Thanks to its community-driven, open-source approach, The Things Network is clearly the network of choice for our Atom-IT sessions, as it allows us to be neutral wrt. the various commercial IoT infrastructures, and as it allows our attendance to take home concrete guidelines allowing them to prototype an IoT solution by themselves.
Practical problems
Organizing a workshop to showcase The Things Network (as in Atom-IT sessions) can be challenging. Although extensive pedagogical material is readily available courtesy of TTN, our workshops are wandering throughout Wallonia (they are hosted by organizations such as universities, high schools, companies, or public entities), which implies that a TTN gateway is rarely readily available wherever the workshops take place.
This is obviously a chicken-and-egg problem: Hobbyists wait for a free IoT network to become readily available before prototyping, but the IoT network is not deployed until people have a need for it (stimulating this need is precisely the goal of the workshops). The solution is of course to punctually deploy a provisional LoRa gateway connected to TTN wherever the workshop takes place, e.g. using a The Things Gateway, a Kerlink station, or a home-made gateway built on Raspberry Pi.
Unfortunately, having one TTN gateway that can be moved around is simply not sufficient. One still must connect this gateway to Internet. This implies a number of practical problems:
- The access to the Intranet of the hosting organization is often blocked for security reasons. This imposes the use of the WiFi connection (and the collection of valid WiFi credentials), for which only the home-made Raspberry-based gateway can be used with the proper WiFi dongle.
- Even when an Ethernet connection is available, we must have tedious discussions with the local network administrators upstream of the workshop, so that DHCP is enabled for the MAC address of the gateway, or so that a temporary static IP address is affected to the gateway.
- The biggest issue consists however in authorizing UPD traffic for the packet forwarder that is necessary for the gateway to communicate with TTN backend.
Solving these problems for each hosting organization is very time-consuming, and needs careful on-site validation before the workshop. Note that besides experimentation workshops, the same problems hold if doing on-site demonstration of any TTN solution.
Solution
In a nutshell, we want to be able to quickly deploy one TTN gateway on-site, and connect it to the TTN back-end independently of the local network infrastructure. The best way is clearly to connect the gateway to the back-end using a 4G mobile data connection. The present story explains a possible way to setup such an infrastructure.
Hardware
Our mobile gateway is made of several hardware components:
- A TTN gateway that is made of iC880a and Raspberry Pi. For the sake of completeness, we use a Raspberry Pi 2 Model B v1.1.
- A GNU/Linux laptop. We use an Ubuntu 16.04 LTS system, but any other distribution would work fine.
- An Android smartphone with a 4G data connection. We use a Samsung Galaxy A3 2016 running Android 6.0.1, but any other smartphone should work fine.
- A standard Ethernet cable. The network device of modern laptops should silently accommodate with straight-through or crossover cables.
- A standard USB to micro-USB cable in order to power the Raspberry Pi from the laptop. We found no necessity to use an external power supply.
Gateway
To setup the hardware of the gateway, we have followed these instructions, ignoring the part about the WiFi dongle. The full list of parts can be found on the latter page. Basically, the assembly consists in plugging the antenna on the IMST iC800a board, then in connecting 9 double-sided female/female jumper wires as follows:
iC880a physical pin | RPi 2 model B physical pin | Description |
21 | 2 | Supply 5V |
22 | 6 | GND |
13 | 22 | Reset |
14 | 23 | SPI SCLK |
15 | 21 | SPI MISO |
16 | 19 | SPI MOSI |
17 | 24 | SPI NSS |
12 | 39 | GND |
18 | 29 | Sx1301 ScanMode Signal |
Some remarks:
- The original instructions do not mention the need to connect the 12 and 18 pins from iC880a. We found out these connections are however mandatory for our TTN gateway to work properly.
- It is recommended to use short jumper wires in order to improve the stability of the gateway.
- Many people also recommend to put the gateway inside a dedicated enclosure.
Thanks to Romain Cambier who provided us with this hardware!
Local network
The gateway hardware is now ready. Remember the network infrastructure we are trying to setup:
We start by configuring the left-hand part of our network, namely the Ethernet connection that will enable the Raspberry Pi to connect to Internet through a GNU/Linux router. For the time being, let's ignore the 4G connection: We make the assumption that the laptop is connected to Internet using some WiFi connection. Here is a diagram summarizing the goal of this section:
The idea here is to setup a private Ethernet subnet that only contains the Raspberry Pi and the laptop. We arbitrarily choose the "192.168.42.0" subnet, but any private IPv4 range would do the job. It is now necessary to configure the laptop as a bridge to Internet. The instructions to this end might vary across GNU/Linux distributions: In this story, we assume Ubuntu 16.04 LTS is being used.
Turning off automatic Ethernet connection
It is highly recommended to turn off the automatic connection to the Ethernet interface within the Ubuntu Network Manager, otherwise the latter would interfere with the network configuration scripts we are about to create:
- Hit Alt-F2, then type "gnome-control-center network" to open the GNOME Network Manager.
- Select the "Wired" connection ("Wired" is the default name of the Ethernet interface under Ubuntu, but you might have another one).
- Enter the "Identity" tab.
- Unselect "Connect automatically" for your Ethernet interface (in our case, "enp2s0", but "eth0" should be more common).
- Click on "Apply".
You will still be able to manually connect to your Ethernet connection using the top-right icons of your Ubuntu desktop manager:
Network configuration scripts
Let's now create two bash scripts that are responsible for starting/stopping the bridge to connect the Raspberry Pi to Internet. Edit a new file called "~/ttn-bridge-start.sh", and copy/paste the following content:
#!/bin/bash
set -e
##
## Configuration
##
# Name of your Ethernet interface (ADAPT IT!)
LAN=enp2s0
# Where to backup the iptables configuration
IPTABLES_BACKUP=/tmp/ttn-bridge-iptables.bak
##
## Automatic detection of the WAN network interface
##
TMP=`/sbin/ip route | awk '/^default / { print $4 }'`
if [ "$TMP" != "dev" ]; then
echo "Unable to find out the network interface of the default gateway"
echo "(Your computer has no access to Internet)"
exit -1
fi
WAN=`/sbin/ip route | awk '/^default / { print $5 }'`
echo "Network interface of the private network for the gateway (LAN): $LAN"
echo "Network interface of the default gateway (WAN): $WAN"
if [ "$LAN" == "$WAN" ]; then
echo "The WAN and the LAN network interfaces are the same: Giving up"
exit -1
fi
##
## Backup of iptables
##
if [ -f "$IPTABLES_BACKUP" ]; then
echo "Restoring the backup of the iptables rules"
sudo iptables-restore < $IPTABLES_BACKUP
else
echo "Creating backup of the iptables rules"
sudo iptables-save > $IPTABLES_BACKUP
fi
##
## Setup the bridge
##
echo "Setting up the LAN-to-WAN bridge"
sudo sysctl -w net.ipv4.ip_forward=1 # Enable IP Forwarding
sudo ifconfig $LAN 192.168.42.1 netmask 255.255.255.0 broadcast 192.168.42.255
sudo iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE
sudo iptables -A FORWARD -i $WAN -o $LAN -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i $LAN -o $WAN -j ACCEPT
Take care of adapting the "LAN" variable above to the name of your Ethernet interface! Now, create a second file called "~/ttn-bridge-stop.sh" with the following content:
#!/bin/bash
set -e
##
## Configuration
##
# Where to backup the iptables configuration
IPTABLES_BACKUP=/tmp/ttn-bridge-iptables.bak
##
## Restoration of iptables
##
if [ -f "$IPTABLES_BACKUP" ]; then
echo "Restoring the backup of the iptables rules"
sudo iptables-restore < $IPTABLES_BACKUP
else
echo "Sorry, no backup of the iptables rules is available"
fi
The script "~/ttn-bridge-start.sh" will setup the Raspberry-to-Internet bridge, whereas the script "~/ttn-bridge-stop.sh" will turn off this bridge. For convenience, tag the two scripts as executable by typing at the command prompt:
$ chmod +x ~/ttn-bridge-start.sh
$ chmod +x ~/ttn-bridge-stop.sh
Note: Be reassured that the modifications made to iptables by the two scripts above are purely transient. Restarting the computer will revert the routing rules.
Raspberry Pi
Now that the local network is ready, we are ready to install the TTN packet forwarder onto the Raspberry Pi.
Install Raspbian
Download the Raspbian Jessie Lite distribution and copy it onto the micro-SD card of the Raspberry Pi. Here is the command line to be used on our Ubuntu 16.04 laptop (make sure to unmount the possibly previously-installed filesystem before running "dd", and to replace "/dev/sdX" by the device corresponding to the micro-SD card):
$ unzip 2017-07-05-raspbian-jessie-lite.zip $ sudo dd status=progress if=2017-07-05-raspbian-jessie-lite.img of=/dev/sdX bs=4M $ sync
Install the SD card within the Raspberry Pi. Connect a monitor and a keyboard to the Raspberry Pi. Connect the Raspberry Pi to the laptop using the Ethernet cable. Finally, boot the Raspberry Pi by connecting it to any USB port of the laptop, and wait until the login message appears.
Configure networking
Log in the Raspberry Pi by using the default credentials (username = pi, password = raspberry). The first operation consists in connecting the RPi to Internet through the private network we setup at the previous step. Open the corresponding configuration file:
$ sudo nano /etc/network/interfaces
Within this file, replace the "iface eth0 inet" line as follows:
# iface eth0 inet
auto eth0
iface eth0 inet static
address 192.168.42.2
netmask 255.255.255.0
network 192.168.42.0
broadcast 192.168.42.255
gateway 192.168.42.1
dns-nameservers 8.8.8.8 8.8.4.4 # Use Google's DNS
Once this modification is done, start the network bridge by typing the following command on the laptop:
$ ~/ttn-bridge-start.sh
You can now start networking on the Raspberry Pi:
$ sudo ifdown eth0 # Forget about the current Ethernet configuration $ sudo ifup eth0 # Re-enable the networking to force reading the new parameters
$ ping www.google.be # Make sure the GNU/Linux router works as expected
Important: After any reboot of the Raspberry Pi or if the Ethernet cable is unplugged, the laptop will loose the Ethernet carrier, which will make Ubuntu forget about the IP address of the private network. As a consequence, don't forget to re-run "~/ttn-bridge-start.sh" after each reboot of the RPi. Note that it is possible to circumvent this issue by using the "ignore-carrier" option of Network Manager (which is unfortunately not supported yet in Ubuntu 16.04), or by defining another so-called "Profile" for the "Wired" connection in the Network Manager.
Install TTN gateway
Now that the Raspberry Pi is connected to Internet, we are ready to configure the TTN gateway:
$ sudo apt-get update $ sudo apt-get upgrade # Upgrade to the latest packages $ sudo rpi-update # Upgrade to the latest RPi firmware (optional step) $ sudo reboot <Log in="" again,="" don't="" forget="" to="" re-run="" <a="" href="<a href=" http:="" ttn-bridge-start.sh"="" rel="nofollow" target="_blank">http://ttn-bridge-start.sh" rel="nofollow" target="_blank">ttn-bridge-start.sh on the laptop> $ sudo raspi-config
This brings us to the configuration tool of the Raspberry Pi. Modify the following options:
- "1 Change User Password", as keeping the "raspberry" default password is definitely a bad idea ;)
- "4 Localisation Options" => "I2 Change Timezone" => select your timezone
- "5 Interfacing Option" => "P2 SSH" => enable SSH server.
- "5 Interfacing Option" => "P4 SPI" => enable SPI to communicate with the iC880a board.
- "7 Advanced Options" => "A1 Expand Filesystem".
Click on "Finish", and choose to reboot. This time, once the Raspberry Pi is started and the "ttn-bridge-start.sh" called, you can log in the Raspberry Pi using SSH from the laptop (i.e. the RPi can be used in a headless mode, with no keyboard and no monitor). Type the following commands on the laptop:
laptop:~ $ ssh pi@192.168.42.2
pi@raspberrypi:~ $ perl
Write down the locales about the missing of which "perl" complains, hit "Ctrl-C", and install the locales using:
pi@raspberrypi:~ $ sudo dpkg-reconfigure locales
Now, reconfigure the time zones and install the TTN gateway (using the SPI branch):
pi@raspberrypi:~ $ sudo dpkg-reconfigure tzdata
pi@raspberrypi:~ $ sudo apt-get install git
pi@raspberrypi:~ $ git clone -b spi https://github.com/ttn-zh/ic880a-gateway.git ~/ic880a-gateway
pi@raspberrypi:~ $ cd ~/ic880a-gateway
pi@raspberrypi:~ $ sudo ./install.sh spi
Register the gateway
The TTN gateway should now be up and running. We need to register it into the Console of The Things Network. First recover the EUID of the gateway as follows:
laptop:~ $ ssh pi@192.168.42.2
pi@raspberrypi:~ $ sudo systemctl status ttn-gateway -l # Make sure the TTN gateway service is running
pi@raspberrypi:~ $ cat /opt/ttn-gateway/bin/local_conf.json { "gateway_conf": { "gateway_ID": "B827xxxxxxxxxxxx", "servers": [ { "server_address": "router.eu.thethings.network", "serv_port_up": 1700, "serv_port_down": 1700, "serv_enabled": true } ], "ref_latitude": 0, "ref_longitude": 0, "ref_altitude": 0, "contact_email": "", "description": "ttn-ic880a" } }
The "gateway_ID" field above contains your EUID. Open the gateway registration page on The Things Network Console, select the "Legacy" packet forwarder, enter your EUI as well as all the required information.
You should now see your gateway up and running in The Things Console! Note that even if the gateway status is displayed as connected, this does not mean that the packet forwarder is actually able to send the received LoRa packets to the TTN backend (because of possible firewall restrictions on UDP).
Improving stability
It is in practice very important to move away the TTN gateway from your laptop, power cables, or monitor (which is possible as our Raspberry Pi is now setup as a fully headless system). Otherwise, you might face a bad stability of the LoRa connection. You might also consider buying a shielding case. In our experience, we use a 3-meter Ethernet cable and an external power supply for smartphones.
4G connection
Now that our home-made TTN gateway is able to send data through the laptop, the remaining step consists in using the 4G mobile network, as depicted in the right-hand side of our schema:
This step is more dependent to your Android and GNU/Linux distribution than the previous steps. We provide some screenshots of Samsung Galaxy and Ubuntu 16.04.
Laptop - Enable Bluetooth
Open the Bluetooth configuration panel:
$ gnome-control-center bluetooth
Associate your smartphone:
Confirm that the number shown by the smartphone corresponds to the number shown by Ubuntu.
Smartphone - Enable tethering
Open the "Settings" of your Android smartphone. "Tethering" is the name of the parameter that allows to setup a mobile access point from your laptop to your 4G connection through Bluetooth.
Obviously, make sure your smartphone has its 4G connection enabled!
Laptop - Connect through Bluetooth
Under Ubuntu, it is then quite straightforward to connect to Internet through your Bluetooth connection:
Finally, make sure that Internet is reachable, and reconfigure your Raspberry-to-Internet bridge:
$ ping www.google.be
$ ~/ttn-bridge-start.sh
Conclusion
To conclude, this story explains how to connect some LoRa gateway to TTN back-end using a standard 4G mobile connection.
Some final remarks
- For this story, we have used an home-made gateway based on the iC880a and Raspberry Pi. Obviously, because our method only uses the Ethernet port of the gateway, it should be compatible with any LoRa gateway supporting TTN: One simply has to configure the IPv4 parameters of the gateway so that is uses the 192.168.42.0 private network with the 192.168.42.1 gateway.
- Don't forget to update the GPS coordinates of your mobile TTN gateway in The Things Console when you move!
- Don't forget to re-run "~/ttn-bridge-start.sh" on the laptop after each reboot of the RPi.
- The script "~/ttn-bridge-stop.sh" will reset the iptables routing rules without having to reboot your laptop.
- It might happen that the TTN gateway freezes and is not able to send packets to the TTN backend (even after restarting the service on the RPi by typing "sudo systemctl restart ttn-gateway"). In such a situation, power off the Raspberry, wait a few minutes, plug in again, and re-run the script "ttn-bridge-start.sh". This might be a consequence of the old version of the "lora_gateway" that is shipped in the automated installer. Further investigation is needed on this point.