2016-03-22 20:40:41 +00:00
|
|
|
#! /bin/bash
|
2016-04-22 18:25:20 +00:00
|
|
|
|
|
|
|
# Exit if we're debugging and haven't yet built the gateway.
|
|
|
|
|
|
|
|
if [ ! -f "ttn-gateway" ]; then
|
|
|
|
echo "ERROR: gateway executable not yet built"
|
|
|
|
exit 1
|
|
|
|
fi
|
2016-03-21 19:36:55 +00:00
|
|
|
|
2016-04-22 18:25:20 +00:00
|
|
|
if [[ $GW_DEBUG != "" ]]; then
|
|
|
|
echo "*** GW_DEBUG asserted - exiting ***"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Show info about the machine we're running on
|
|
|
|
|
|
|
|
echo "*** Resin Machine Info:"
|
|
|
|
echo "*** Type: $RESIN_MACHINE_NAME"
|
|
|
|
echo "*** Architecture: $RESIN_ARCH"
|
|
|
|
|
|
|
|
##### Raspberry Pi 3 hacks necessary for LinkLabs boards
|
2016-04-22 16:07:18 +00:00
|
|
|
##
|
2016-04-22 18:25:20 +00:00
|
|
|
## Because of backward incompatibility between RPi2 and RPi3,
|
|
|
|
## a hack is necessary to get serial working so that we can
|
|
|
|
## access the GPS on the LinkLabs board.
|
2016-04-22 16:07:18 +00:00
|
|
|
##
|
|
|
|
## Option #1: Leave RPi serial on /dev/ttyS0 and bluetooth on /dev/ttyAMA0
|
2016-04-22 18:25:20 +00:00
|
|
|
## This requires adding this Fleet Configuration variable, which
|
2016-04-22 16:07:18 +00:00
|
|
|
## fixes RPi3 serial port speed issues:
|
|
|
|
## RESIN_HOST_CONFIG_core_freq = 250
|
|
|
|
##
|
|
|
|
## Option #2: Disable bluetooth and put RPi serial back onto /dev/ttyAMA0
|
2016-04-22 18:25:20 +00:00
|
|
|
## This requires adding this Fleet Configuration variable, which
|
|
|
|
## swaps the bluetooth and serial uarts:
|
2016-04-22 16:07:18 +00:00
|
|
|
## RESIN_HOST_CONFIG_dtoverlay=pi3-miniuart-bt
|
|
|
|
##
|
|
|
|
#####
|
2016-03-29 22:27:49 +00:00
|
|
|
|
2016-04-22 18:25:20 +00:00
|
|
|
if [[ $GW_TYPE == "" ]]; then
|
|
|
|
echo "ERROR: GW_TYPE required"
|
|
|
|
echo "See https://github.com/rayozzie/ttn-resin-gateway-rpi/blob/master/README.md"
|
2016-03-29 22:27:49 +00:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2016-04-22 18:25:20 +00:00
|
|
|
if [[ $GW_TYPE == "linklabs-dev" && "$RESIN_MACHINE_NAME" == "raspberrypi3" ]]
|
|
|
|
then
|
|
|
|
echo "*** Raspberry Pi 3 with LinkLabs board"
|
2016-04-22 18:39:46 +00:00
|
|
|
if [[ "$RESIN_HOST_CONFIG_dtoverlay" == "pi3-miniuart-bt" ]]
|
2016-04-22 18:25:20 +00:00
|
|
|
then
|
|
|
|
echo "*** Operating with Bluetooth disabled, and UART swapped onto /dev/ttyAMA0"
|
|
|
|
if [[ "$RESIN_HOST_CONFIG_core_freq" != "" ]]
|
|
|
|
then
|
|
|
|
echo "ERROR: Fleet configuration can only have EITHER dtoverlay OR core_freq, but not both."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
elif [[ "$RESIN_HOST_CONFIG_core_freq" == "250" ]]
|
2016-04-22 18:39:46 +00:00
|
|
|
then
|
|
|
|
echo "*** Operating with Bluetooth enabled, and UART frequency adjusted to work properly"
|
2016-04-22 18:25:20 +00:00
|
|
|
else
|
|
|
|
echo "*** Please add one of these two Resin Fleet Configuration variables (but not both)"
|
|
|
|
echo "*** If there is some reason you need Bluetooth (which is unlikely):"
|
|
|
|
echo "*** RESIN_HOST_CONFIG_dtoverlay=pi3-miniuart-bt"
|
|
|
|
echo "*** Otherwise:"
|
2016-04-22 18:39:46 +00:00
|
|
|
echo "*** RESIN_HOST_CONFIG_core_freq=250"
|
2016-04-22 18:25:20 +00:00
|
|
|
exit 1
|
|
|
|
fi
|
2016-04-22 17:47:19 +00:00
|
|
|
|
2016-04-22 18:25:20 +00:00
|
|
|
fi
|
2016-04-22 17:47:19 +00:00
|
|
|
|
2016-03-28 23:48:33 +00:00
|
|
|
# We need to be online, wait if needed.
|
|
|
|
|
2016-04-10 19:23:51 +00:00
|
|
|
until $(curl --output /dev/null --silent --head --fail http://www.google.com); do
|
2016-03-28 23:48:33 +00:00
|
|
|
echo "[TTN Gateway]: Waiting for internet connection..."
|
|
|
|
sleep 30
|
|
|
|
done
|
|
|
|
|
2016-03-25 18:21:04 +00:00
|
|
|
# Ensure that we've got the required env vars
|
2016-03-21 21:20:50 +00:00
|
|
|
|
2016-03-22 23:35:24 +00:00
|
|
|
echo "*******************"
|
2016-03-22 04:10:53 +00:00
|
|
|
echo "*** Configuration:"
|
2016-03-22 23:35:24 +00:00
|
|
|
echo "*******************"
|
2016-03-21 21:20:50 +00:00
|
|
|
|
2016-03-22 20:03:58 +00:00
|
|
|
if [[ $GW_REGION == "" ]]; then
|
2016-03-22 20:23:35 +00:00
|
|
|
echo "ERROR: GW_REGION required"
|
2016-03-26 16:19:19 +00:00
|
|
|
exit 1
|
2016-03-22 17:45:40 +00:00
|
|
|
fi
|
2016-03-22 20:03:58 +00:00
|
|
|
echo GW_REGION: $GW_REGION
|
2016-03-22 17:45:40 +00:00
|
|
|
|
2016-03-22 20:03:58 +00:00
|
|
|
if [[ $GW_DESCRIPTION == "" ]]; then
|
2016-03-22 20:23:35 +00:00
|
|
|
echo "ERROR: GW_DESCRIPTION required"
|
2016-04-16 22:05:52 +00:00
|
|
|
echo "See https://github.com/rayozzie/ttn-resin-gateway-rpi/blob/master/README.md"
|
2016-03-22 18:09:32 +00:00
|
|
|
exit 1
|
2016-03-21 21:20:50 +00:00
|
|
|
fi
|
|
|
|
|
2016-03-22 20:03:58 +00:00
|
|
|
if [[ $GW_CONTACT_EMAIL == "" ]]; then
|
2016-03-22 20:23:35 +00:00
|
|
|
echo "ERROR: GW_CONTACT_EMAIL required"
|
2016-04-16 22:05:52 +00:00
|
|
|
echo "See https://github.com/rayozzie/ttn-resin-gateway-rpi/blob/master/README.md"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2016-03-22 04:10:53 +00:00
|
|
|
echo "******************"
|
2016-03-21 21:20:50 +00:00
|
|
|
echo ""
|
|
|
|
|
2016-03-25 18:22:57 +00:00
|
|
|
# Load the region-appropriate global config
|
2016-03-22 17:45:40 +00:00
|
|
|
|
2016-03-25 17:23:18 +00:00
|
|
|
if curl -sS --fail https://raw.githubusercontent.com/TheThingsNetwork/gateway-conf/master/$GW_REGION-global_conf.json --output ./global_conf.json
|
2016-03-22 17:45:40 +00:00
|
|
|
then
|
2016-03-22 20:03:58 +00:00
|
|
|
echo Successfully loaded $GW_REGION-global_conf.json from TTN repo
|
2016-03-22 18:09:32 +00:00
|
|
|
else
|
2016-03-22 17:45:40 +00:00
|
|
|
echo "******************"
|
2016-03-22 20:03:58 +00:00
|
|
|
echo "ERROR: GW_REGION not found"
|
2016-03-22 17:45:40 +00:00
|
|
|
echo "******************"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2016-03-25 18:21:04 +00:00
|
|
|
# Fetch location info, which we'll use as a hint to the gateway software
|
2016-03-22 21:54:00 +00:00
|
|
|
|
|
|
|
if curl -sS --fail ipinfo.io --output ./ipinfo.json
|
|
|
|
then
|
2016-03-22 22:26:55 +00:00
|
|
|
echo "Actual gateway location:"
|
2016-03-22 21:54:00 +00:00
|
|
|
IPINFO=$(cat ./ipinfo.json)
|
|
|
|
echo $IPINFO
|
|
|
|
else
|
|
|
|
echo "Unable to determine gateway location"
|
|
|
|
IPINFO="\"\""
|
|
|
|
fi
|
|
|
|
|
2016-03-25 18:21:04 +00:00
|
|
|
# Set up environmental defaults for local.conf
|
2016-03-22 20:03:58 +00:00
|
|
|
|
2016-04-10 19:46:57 +00:00
|
|
|
if [[ $GW_REF_LATITUDE == "" ]]; then GW_REF_LATITUDE="52.376364"; fi
|
|
|
|
if [[ $GW_REF_LONGITUDE == "" ]]; then GW_REF_LONGITUDE="4.884232"; fi
|
|
|
|
if [[ $GW_REF_ALTITUDE == "" ]]; then GW_REF_ALTITUDE="3"; fi
|
|
|
|
|
2016-03-22 20:58:07 +00:00
|
|
|
if [[ $GW_GPS == "" ]]; then GW_GPS="true"; fi
|
|
|
|
if [[ $GW_BEACON == "" ]]; then GW_BEACON="false"; fi
|
|
|
|
if [[ $GW_MONITOR == "" ]]; then GW_MONITOR="false"; fi
|
|
|
|
if [[ $GW_UPSTREAM == "" ]]; then GW_UPSTREAM="true"; fi
|
|
|
|
if [[ $GW_DOWNSTREAM == "" ]]; then GW_DOWNSTREAM="true"; fi
|
|
|
|
if [[ $GW_GHOSTSTREAM == "" ]]; then GW_GHOSTSTREAM="false"; fi
|
|
|
|
if [[ $GW_RADIOSTREAM == "" ]]; then GW_RADIOSTREAM="true"; fi
|
|
|
|
if [[ $GW_STATUSSTREAM == "" ]]; then GW_STATUSSTREAM="true"; fi
|
2016-03-22 20:03:58 +00:00
|
|
|
|
2016-03-22 20:58:07 +00:00
|
|
|
if [[ $GW_KEEPALIVE_INTERVAL == "" ]]; then GW_KEEPALIVE_INTERVAL="10"; fi
|
|
|
|
if [[ $GW_STAT_INTERVAL == "" ]]; then GW_STAT_INTERVAL="30"; fi
|
|
|
|
if [[ $GW_PUSH_TIMEOUT_MS == "" ]]; then GW_PUSH_TIMEOUT_MS="100"; fi
|
2016-03-22 20:03:58 +00:00
|
|
|
|
2016-03-22 20:58:07 +00:00
|
|
|
if [[ $GW_FORWARD_CRC_VALID == "" ]]; then GW_FORWARD_CRC_VALID="true"; fi
|
|
|
|
if [[ $GW_FORWARD_CRC_ERROR == "" ]]; then GW_FORWARD_CRC_ERROR="false"; fi
|
|
|
|
if [[ $GW_FORWARD_CRC_DISABLED == "" ]]; then GW_FORWARD_CRC_DISABLED="false"; fi
|
2016-03-22 20:03:58 +00:00
|
|
|
|
2016-04-22 18:25:20 +00:00
|
|
|
if [[ $GW_GPS_TTY_PATH == "" ]]
|
|
|
|
then
|
|
|
|
# Default to AMA0 unless this is an RPi3 with core frequency set in fleet config vars
|
|
|
|
GW_GPS_TTY_PATH="/dev/ttyAMA0"
|
|
|
|
if [[ "$RESIN_MACHINE_NAME" == "raspberrypi3" && "$RESIN_HOST_CONFIG_core_freq" != "" ]]
|
|
|
|
then
|
|
|
|
GW_GPS_TTY_PATH="/dev/ttyS0"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
2016-04-10 19:32:09 +00:00
|
|
|
if [[ $GW_FAKE_GPS == "" ]]; then GW_FAKE_GPS="false"; fi
|
2016-03-22 20:03:58 +00:00
|
|
|
|
2016-04-22 14:25:48 +00:00
|
|
|
if [[ $GW_GHOST_ADDRESS == "" ]]; then GW_GHOST_ADDRESS="127.0.0.1"; fi
|
2016-03-22 20:58:07 +00:00
|
|
|
if [[ $GW_GHOST_PORT == "" ]]; then GW_GHOST_PORT="1918"; fi
|
2016-03-22 20:03:58 +00:00
|
|
|
|
2016-04-22 14:25:48 +00:00
|
|
|
if [[ $GW_MONITOR_ADDRESS == "" ]]; then GW_MONITOR_ADDRESS="127.0.0.1"; fi
|
2016-03-22 20:58:07 +00:00
|
|
|
if [[ $GW_MONITOR_PORT == "" ]]; then GW_MONITOR_PORT="2008"; fi
|
2016-03-22 20:03:58 +00:00
|
|
|
|
2016-04-22 14:25:48 +00:00
|
|
|
if [[ $GW_SSH_PATH == "" ]]; then GW_SSH_PATH="/usr/bin/ssh"; fi
|
2016-03-22 20:58:07 +00:00
|
|
|
if [[ $GW_SSH_PORT == "" ]]; then GW_SSH_PORT="22"; fi
|
2016-03-22 20:03:58 +00:00
|
|
|
|
2016-03-22 20:58:07 +00:00
|
|
|
if [[ $GW_HTTP_PORT == "" ]]; then GW_HTTP_PORT="80"; fi
|
2016-03-22 20:03:58 +00:00
|
|
|
|
2016-04-22 14:25:48 +00:00
|
|
|
if [[ $GW_NGROK_PATH == "" ]]; then GW_NGROK_PATH="/usr/bin/ngrok"; fi
|
2016-03-22 20:03:58 +00:00
|
|
|
|
2016-03-22 20:58:07 +00:00
|
|
|
if [[ $GW_SYSTEM_CALLS == "" ]]; then GW_SYSTEM_CALLS="[\"df -m\",\"free -h\",\"uptime\",\"who -a\",\"uname -a\"]"; fi
|
2016-03-22 20:03:58 +00:00
|
|
|
|
2016-04-22 14:25:48 +00:00
|
|
|
if [[ $GW_PLATFORM == "" ]]; then GW_PLATFORM="*"; fi
|
2016-03-22 20:03:58 +00:00
|
|
|
|
2016-03-25 18:21:04 +00:00
|
|
|
# Synthesize local.conf JSON from env vars
|
2016-03-22 17:45:40 +00:00
|
|
|
|
2016-03-22 19:09:41 +00:00
|
|
|
echo -e "{\n\
|
|
|
|
\t\"gateway_conf\": {\n\
|
2016-03-22 20:03:58 +00:00
|
|
|
\t\t\"ref_latitude\": $GW_REF_LATITUDE,\n\
|
|
|
|
\t\t\"ref_longitude\": $GW_REF_LONGITUDE,\n\
|
|
|
|
\t\t\"ref_altitude\": $GW_REF_ALTITUDE,\n\
|
|
|
|
\t\t\"contact_email\": \"$GW_CONTACT_EMAIL\",\n\
|
2016-03-22 20:58:07 +00:00
|
|
|
\t\t\"description\": \"$GW_DESCRIPTION\", \n\
|
2016-03-22 20:40:41 +00:00
|
|
|
\t\t\"gps\": $GW_GPS,\n\
|
|
|
|
\t\t\"beacon\": $GW_BEACON,\n\
|
|
|
|
\t\t\"monitor\": $GW_MONITOR,\n\
|
|
|
|
\t\t\"upstream\": $GW_UPSTREAM,\n\
|
|
|
|
\t\t\"downstream\": $GW_DOWNSTREAM,\n\
|
|
|
|
\t\t\"ghoststream\": $GW_GHOSTSTREAM,\n\
|
|
|
|
\t\t\"radiostream\": $GW_RADIOSTREAM,\n\
|
|
|
|
\t\t\"statusstream\": $GW_STATUSSTREAM,\n\
|
|
|
|
\t\t\"keepalive_interval\": $GW_KEEPALIVE_INTERVAL,\n\
|
|
|
|
\t\t\"stat_interval\": $GW_STAT_INTERVAL,\n\
|
|
|
|
\t\t\"push_timeout_ms\": $GW_PUSH_TIMEOUT_MS,\n\
|
|
|
|
\t\t\"forward_crc_valid\": $GW_FORWARD_CRC_VALID,\n\
|
|
|
|
\t\t\"forward_crc_error\": $GW_FORWARD_CRC_ERROR,\n\
|
|
|
|
\t\t\"forward_crc_disabled\": $GW_FORWARD_CRC_DISABLED,\n\
|
2016-04-22 14:25:48 +00:00
|
|
|
\t\t\"gps_tty_path\": \"$GW_GPS_TTY_PATH\",\n\
|
2016-03-22 20:40:41 +00:00
|
|
|
\t\t\"fake_gps\": $GW_FAKE_GPS,\n\
|
2016-04-22 14:25:48 +00:00
|
|
|
\t\t\"ghost_address\": \"$GW_GHOST_ADDRESS\",\n\
|
2016-03-22 20:40:41 +00:00
|
|
|
\t\t\"ghost_port\": $GW_GHOST_PORT,\n\
|
2016-04-22 14:25:48 +00:00
|
|
|
\t\t\"monitor_address\": \"$GW_MONITOR_ADDRESS\",\n\
|
2016-03-22 20:40:41 +00:00
|
|
|
\t\t\"monitor_port\": $GW_MONITOR_PORT,\n\
|
2016-04-22 14:25:48 +00:00
|
|
|
\t\t\"ssh_path\": \"$GW_SSH_PATH\",\n\
|
2016-03-22 20:40:41 +00:00
|
|
|
\t\t\"ssh_port\": $GW_SSH_PORT,\n\
|
|
|
|
\t\t\"http_port\": $GW_HTTP_PORT,\n\
|
2016-04-22 14:25:48 +00:00
|
|
|
\t\t\"ngrok_path\": \"$GW_NGROK_PATH\",\n\
|
2016-03-22 20:40:41 +00:00
|
|
|
\t\t\"system_calls\": $GW_SYSTEM_CALLS,\n\
|
2016-04-22 14:25:48 +00:00
|
|
|
\t\t\"platform\": \"$GW_PLATFORM\",\n\
|
2016-03-22 21:54:00 +00:00
|
|
|
\t\t\"ipinfo\": $IPINFO,\n\
|
2016-03-22 20:58:07 +00:00
|
|
|
\t\t\"gateway_ID\": \"0000000000000000\"\n\
|
2016-03-22 18:45:20 +00:00
|
|
|
\t}\n\
|
|
|
|
}" >./local_conf.json
|
2016-03-21 21:20:50 +00:00
|
|
|
|
2016-03-25 18:21:04 +00:00
|
|
|
# Set gateway_ID in local_conf.json to the gateway's MAC address
|
2016-03-21 22:58:37 +00:00
|
|
|
|
2016-03-22 04:10:53 +00:00
|
|
|
echo "******************"
|
2016-03-29 22:27:49 +00:00
|
|
|
./set-gateway-id.sh start ./local_conf.json
|
2016-03-22 04:10:53 +00:00
|
|
|
echo "******************"
|
2016-03-21 22:58:37 +00:00
|
|
|
echo ""
|
|
|
|
|
2016-04-16 22:05:52 +00:00
|
|
|
# Reset the board to a known state prior to launching the forwarder
|
2016-03-26 19:18:15 +00:00
|
|
|
|
2016-04-16 22:05:52 +00:00
|
|
|
if [[ $GW_TYPE == "imst-ic880a-spi" ]]; then
|
2016-04-16 22:25:11 +00:00
|
|
|
echo "Resetting IMST iC880A-SPI"
|
|
|
|
gpio -1 mode 22 out
|
|
|
|
gpio -1 write 22 0
|
|
|
|
sleep 0.1
|
|
|
|
gpio -1 write 22 1
|
|
|
|
sleep 0.1
|
|
|
|
gpio -1 write 22 0
|
|
|
|
sleep 0.1
|
2016-04-16 22:13:27 +00:00
|
|
|
elif [[ $GW_TYPE == "linklabs-dev" ]]; then
|
2016-04-16 22:25:11 +00:00
|
|
|
echo "Resetting LinkLabs Raspberry Pi Development Board"
|
|
|
|
gpio -1 mode 29 out
|
|
|
|
gpio -1 write 29 0
|
|
|
|
sleep 0.1
|
|
|
|
gpio -1 write 29 1
|
|
|
|
sleep 0.1
|
|
|
|
gpio -1 write 29 0
|
2016-04-16 22:28:59 +00:00
|
|
|
sleep 0.1
|
2016-04-16 22:05:52 +00:00
|
|
|
else
|
|
|
|
echo "ERROR: unrecognized GW_TYPE=$GW_TYPE"
|
|
|
|
echo "See https://github.com/rayozzie/ttn-resin-gateway-rpi/blob/master/README.md"
|
|
|
|
exit 1
|
|
|
|
fi
|
2016-03-26 19:18:15 +00:00
|
|
|
|
2016-03-21 19:36:55 +00:00
|
|
|
# Fire up the forwarder.
|
2016-03-25 18:21:04 +00:00
|
|
|
|
2016-03-21 19:36:55 +00:00
|
|
|
while true
|
|
|
|
do
|
|
|
|
echo "[TTN Gateway]: Starting packet forwarder..."
|
2016-03-29 22:27:49 +00:00
|
|
|
./ttn-gateway
|
2016-03-22 04:10:53 +00:00
|
|
|
echo "******************"
|
2016-03-22 04:21:11 +00:00
|
|
|
echo "*** [TTN Gateway]: EXIT (retrying in 15s)"
|
2016-03-22 04:10:53 +00:00
|
|
|
echo "******************"
|
2016-03-21 19:36:55 +00:00
|
|
|
sleep 15
|
|
|
|
done
|