Gruppo Meteo/HowTo/LorawanGateway

Da raspibo.
Jump to navigation Jump to search

LoRaWAN Gateway on rapberry, IMST iC880A Concentrator 868MHz, Centos 7

Main characteristics

  • User lorawan packet forwarder ( TTN legacy mode )
  • Remote access using ssh tunneling
  • Hardware reset for IMST concentrator
  • Autorestart services and network connections
  • Use system users for services (none run as root or privileged users)
  • All software (not configuration) is packaged and use standard public repo (not signed)
  • Use firewalld

Assemble the gateway

Parts:

Assemble the gateway as described at: https://github.com/ttn-zh/ic880a-gateway/wiki

Regulate the DC-DC power Supply to output 5.0V Connect the capacitor to the output of DC-DC power Supply Connect power supply to DC-DC input Connect DC-DC output to raspberry

Operative system

Follow https://wiki.centos.org/SpecialInterestGroup/AltArch/Arm32/RaspberryPi3

enable epel:

cat > /etc/yum.repos.d/epel.repo << EOF
[epel]
name=Epel rebuild for armhfp
baseurl=https://armv7.dev.centos.org/repodir/epel-pass-1/
enabled=1
gpgcheck=0

EOF

enable ttn:

cd /etc/yum.repos.d
wget http://rmap.cc/repo/ttn/rmapcentos.repo


change root password!

Install packages

TOBEDONE


chkconfig ttn-gateway on chkconfig ttn-imstreset-setgpio on


Autossh

  • attivare autossh, ossia un tunneling ssh su macchina pubblica per

permettere l'accesso remoto di amministrazione; infatti la connesione tramite wifi o ethernet o GSM non espongono un ip pubblico (almeno senza fare un reindirizzamento di porta):

yum install autossh da root:

ssh-keygen
ssh-copy-id 

/usr/lib/systemd/system/autossh.service

[Unit]
Description=Autossh tunneling
After=network.target

[Service]
#User=ttn
#Group=ttn
WorkingDirectory=/root
#ExecStart=/usr/bin/autossh -M 5023  -N -R 5022:localhost:22 pat1@ttn.rmap.it
ExecStart=/usr/bin/autossh -M 0 -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -N -R 5022:localhost:22 <user>@<remotehost>
SyslogIdentifier=autossh
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
service autossh start
chkconfig autossh on

ora dalla macchina remota si può fare:

ssh root@localhost -p5022

Pulsante poweoff

dnf install dbusgpio

/etc/dbus-1/system.d/dbusgpio.conf

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">

<busconfig>

 <policy user="root">
   <allow send_destination="org.gpio.myboard.Pins"/>
   <allow own="org.gpio.myboard.Pins"/>
 </policy>

 <policy context="default">
   <allow receive_interface="org.gpio.myboard.Pins"/>
 </policy>

</busconfig>

/etc/dbusgpio/dbusgpio-site.cfg

[dbusgpiod]

logfile  = '/var/log/dbusgpio/dbusgpiod.log'
errfile  = '/var/log/dbusgpio/dbusgpiod.err'
lockfile = '/var/run/dbusgpiod.lock'

busaddress='systembus'
pinlist= 18,

/usr/local/bin/poweroffd

#!/usr/bin/env python
# GPL. (C) 2014 Paolo Patruno.

# This program is free software; you can redistribute it and/or modify 
# it under the terms of the GNU General Public License as published by 
# the Free Software Foundation; either version 2 of the License, or 
# (at your option) any later version. 
# 
# This program is distributed in the hope that it will be useful, 
# but WITHOUT ANY WARRANTY; without even the implied warranty of 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
# GNU General Public License for more details. 
# 
# You should have received a copy of the GNU General Public License 
# along with this program; if not, write to the Free Software 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
# 

from dbusgpio import daemon
import dbus
import dbus.mainloop.glib
import gobject

#busaddress='tcp:host=192.168.1.180,port=1234'
busaddress=None

poweroffd = daemon.Daemon(
       stdin="/dev/null",
       stdout="/var/log/dbusgpio/poweroffd.log",
       stderr="/var/log/dbusgpio/poweroffd.err",
       pidfile="/var/run/poweroffd.lock",
#        user=autoradio.settings.user,
#        group=autoradio.settings.group
)

def poweroff():

   bus = dbus.SystemBus()
   ck = bus.get_object('org.freedesktop.login1',
                       '/org/freedesktop/login1')    
   p = dbus.Interface(ck,dbus_interface='org.freedesktop.login1.Manager')
   p.PowerOff(True)


def signal_handler(interface,properties,arg0):
   print "signal received"
   print "interface=",interface
   for prop in properties.keys():
       print prop, properties[prop]
       if prop == "Status" and properties[prop] == 0 :
           poweroff()
   #print arg0


def main(self):

   dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

   if busaddress is None:
       bus = dbus.SystemBus()
   else:
       bus = dbus.bus.BusConnection(busaddress)

   proxy = bus.get_object('org.gpio.myboard.Pins','/org/gpio/myboard')
   properties_manager = dbus.Interface(proxy, 'org.freedesktop.DBus.Properties')
   board_manager= dbus.Interface(proxy, 'org.gpio.myboard')

   if not properties_manager.Get('org.gpio.myboard', 'Running'):
       # start management of board pins
       board_manager.Raise('org.gpio.myboard')

   #pin 18 in
   properties_manager.Set('org.gpio.myboard.pins.channel18','Pull',"up")
   properties_manager.Set('org.gpio.myboard.pins.channel18','Mode',"in")
   print "18 status=", properties_manager.Get('org.gpio.myboard.pins.channel18','Status')

   bus.add_signal_receiver(signal_handler, dbus_interface = dbus.PROPERTIES_IFACE, signal_name = "PropertiesChanged")

   try:  
       loop = gobject.MainLoop()
       loop.run()

   except KeyboardInterrupt :
       # exit the management daemon
       board_manager.Quit('org.gpio.myboard')

if __name__ == '__main__':

   import sys, os
   poweroffd.cwd=os.getcwd()

   if poweroffd.service():

       sys.stdout.write("Daemon started with pid %d\n" % os.getpid())
       sys.stdout.write("Daemon stdout output\n")
       sys.stderr.write("Daemon stderr output\n")

       main(poweroffd)  # (this code was run as script)

       for proc in poweroffd.procs:
           proc.wait()

       sys.exit(0)

Assemblaggio

Connettere un pulsante normalmente apertro tra:

  • Physical pin 12; BCM pin 18; Wiring Pi pin 1
  • Physical pin 14; Ground


GSM

/etc/NetworkManager/system-connections

this for Vodafone:

[connection]
id=vodafone
uuid=9799d176-4b87-480b-82a8-d744f6f9959a
type=gsm
permissions=

[gsm]
apn=mobile.vodafone.it
number=*99#

[ipv4]
dns-search=
method=auto

[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=auto

this for TIM:

[connection]
id=TIM Maxxi Alice/Internet
uuid=67a55a9d-c19b-479f-8dd9-ea0a4fb23282
type=gsm
autoconnect=true
autoconnect-retries=0
permissions=

[gsm]
apn=ibox.tim.it
number=*99#

[serial]
baud=115200

[ipv4]
dns-search=
method=auto

[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=ignore

or use:

nmcli connection edit type gsm con-name "mio provider"

The only thing you are likely to need to edit is the APN of your network. This can be set with set gsm.apn <APN> where APN would be something like ibox.tim.it after:

save

WIFI

installare in /lib/firmware/brcm/

https://raw.githubusercontent.com/RPi-Distro/firmware-nonfree/master/brcm/brcmfmac43455-sdio.txt

Monit

GSM

/usr/local/bin/start_gsm (change usb_modeswitch command and serial port to adapt to your gsm modem):

#!/bin/bash
/sbin/usb_modeswitch -v 12d1 -p 14fe -c /usr/share/usb_modeswitch/12d1:14fe
sleep 10
/usr/bin/nmcli device connect ttyUSB2
chmod +x /usr/local/bin/start_gsm

/usr/local/bin/stop_gsm

#!/bin/bash
/usr/bin/nmcli device disconnect ttyUSB2
chmod +x /usr/local/bin/stop_gsm

/usr/local/bin/check_gsm

#!/bin/bash
set -e

# "Check Mobile Broadband Connection." 

# testing...to see if gsm is on the list of active devices

       LC_ALL=C nmcli -t -f TYPE,STATE dev | grep -q "^gsm:connected$"

/etc/monit.d/gsm-connection

check host google_ping with address google.com
   if failed ping then restart

   start program = "/usr/local/bin/start_gsm"
   stop program  = "/usr/local/bin/stop_gsm"
   depends on check_gsm

CHECK PROGRAM check_gsm PATH /usr/local/bin/check_gsm TIMEOUT 30 SECONDS
   if status != 0 then restart

   start program = "/usr/local/bin/start_gsm"
   stop program  = "/usr/local/bin/stop_gsm"

Packet forwarder

/usr/local/bin/check_gateway (change your gateway id and coordinate):

#!/usr/bin/python

import urllib2
import json
import dateutil.parser
import datetime
import sys

GATEWAYID="eui-0ceee6fffe9da82e"
LAT="44.48842723017417"
LON="11.26079806901295"

body=urllib2.urlopen("https://www.thethingsnetwork.org/gateway-data/location?latitude="+LAT+"&longitude="+LON+"&distance=15000").read()
gatewaydata=json.loads(body)
print gatewaydata[GATEWAYID]["last_seen"]

lastseen = dateutil.parser.parse(gatewaydata[GATEWAYID]["last_seen"]).replace(tzinfo=None)
now=datetime.datetime.utcnow()
print lastseen
print now

elapsed=now-lastseen
print "elapsed: ", elapsed
if ( elapsed > datetime.timedelta(seconds=300)):
   sys.exit(1)

sys.exit(0)

/etc/monit.d/gateway-connection

CHECK PROGRAM gateway-connection PATH /usr/local/bin/check_gateway TIMEOUT 30 SECONDS
   if status != 0 then restart

   start program = "/usr/sbin/service ttn-gateway start"
   stop program  = "/usr/sbin/service ttn-gateway stop"

   every 5 cycles

Power off

/etc/monit.d/poweroff

check process dbusgpiod with pidfile /var/run/dbusgpiod.lock

   start program = "/bin/dbusgpiod restart"
   stop program  = "/bin/dbusgpiod stop"


check process poweroffd with pidfile /var/run/poweroffd.lock

   start program = "/usr/local/bin/poweroffd restart"
   stop program  = "/usr/local/bin/poweroffd stop"
   depends on dbusgpiod

Activate monit

chkconfig monit on
service monit start


BlueTooth

assicurarsi che in /boot/cmdline.txt non ci sia nessun riferimento a AMA0

( rimuovere console=ttyAMA0,115200 )


/usr/lib/systemd/system/pi-bluetooth.hciuart.service

[Unit]
Description=Configure Bluetooth Modems connected by UART
ConditionPathIsDirectory=/proc/device-tree/soc/gpio@7e200000/bt_pins
Before=bluetooth.service
Wants=dev-serial1.device
After=dev-serial1.device

[Service]
Type=forking
ExecStart=/usr/bin/btuart

[Install]
WantedBy=multi-user.target

/usr/bin/btuart

#!/bin/sh
set -x

HCIATTACH=/usr/bin/hciattach
SERIAL=`grep Serial /proc/cpuinfo | cut -c19-`
B1=`echo $SERIAL | cut -c3-4`
B2=`echo $SERIAL | cut -c5-6`
B3=`echo $SERIAL | cut -c7-8`
BDADDR=`printf b8:27:eb:%02x:%02x:%02x $((0x$B1 ^ 0xaa)) $((0x$B2 ^ 0xaa)) $((0x$B3 ^ 0xaa))` 
if [ "$(cat /proc/device-tree/aliases/uart0)" = "$(cat /proc/device-tree/aliases/serial1)" ] ; then
   if [ "$(wc -c /proc/device-tree/soc/gpio@7e200000/uart0_pins/brcm\,pins | cut -f 1 -d ' ')" = "16" ] ; then
   $HCIATTACH /dev/ttyAMA0 bcm43xx 3000000 flow - $BDADDR
   else
   $HCIATTACH /dev/ttyAMA0 bcm43xx 921600 noflow - $BDADDR
   fi
else
   $HCIATTACH /dev/ttyAMA0 bcm43xx 460800 noflow - $BDADDR
fi


chkconfig pi-bluetooth.hciuart on
reboot
bluetoothctl

power on
agent on
scan on

pair <address>


Firewall

dnf install firewalld
chkconfig firewalld on
service firewalld start
firewall-cmd --set-default-zone=block
firewall-cmd --permanent --zone=block --add-service=ssh
firewall-cmd --permanent --zone=block --add-service=dns

Accesso remoto

Tramite consol su porta seriale

Assicurarsi che nel file /boot/cmdline.txt /boot/cmdline.txt sia apresente

console=ttyS0,115200
Attivare nel "/boot/config.txt" la voce "enable_uart=1" 

(riferimenti: https://www.raspberrypi.org/documentation/configuration/uart.md)

https://elinux.org/RPi_Serial_Connection
https://pinout.xyz/#

sul pc per visualizzare la console:

picocom -b 115200 /dev/ttyUSB0

Tramite Bluetooth

/usr/lib/systemd/system/bluetooth.service

ExecStart=/usr/libexec/bluetooth/bluetoothd --compat
service bluetooth restart

Per far ignorare la porta seriale a ModemManager in /etc/udev/rules.d/90-rfcomm.rules, please put the following line:

KERNEL=="rfcomm[0-9]*", ENV{ID_MM_DEVICE_IGNORE}="1"

/etc/ppp/options

lock
local
nodetach
sdptool browse local
sdptool add --channel=3 SP
echo "pairable on" |bluetoothctl
echo "discoverable on" |bluetoothctl
echo "default-agent" |bluetoothctl

bluetoothctl

  agent on
rfcomm -r watch 0 3 pppd 192.168.13.1:192.168.13.2 /dev/rfcomm0 115200

dall'altro lato (pc client)

usare blueman-manager per accoppiare il bluetooth

(rispondere sulla console di bluetoothctl

/etc/ppp/options

lock
local
nodetach

e eseguire:

pppd /dev/rfcomm0

ssh root@192.168.13.1


QUESTO NON C'E` VERSO DI FARLO FUNZIONARE ci sono problemi con PAM ma principalmente con ioctl sul device rfcomm Una possibilità sarebbe quella di utilizzare pppd

Per poter accedere come root in /etc/securetty aggiungere rfcomm0

rfcomm watch 0 3 /sbin/agetty -L -c -J rfcomm0 115200 linux

oppure:

rfcomm watch 0 3
/sbin/agetty -L -c -J rfcomm0 115200 linux

see at: https://docs.ubuntu.com/core/en/stacks/bluetooth/bluez/docs/reference/pairing/inbound

Tramite wifi

AP

Non far gestire il device a NetworkManager

aggiungere in /etc/NetworkManager/conf.d/lora_gateway.conf

[keyfile]
unmanaged-devices=interface-name:wlan0

se presenti altri device separare con la ","

Attivare Access Point
cd
cd git
git clone https://github.com/r-map/create_ap.git
cd create_ap
make install

modificare la password in:

/etc/create_ap.conf
systemctl enable create_ap
systemctl restart create_ap

Attivare sul proprio pc la connessio wifi con SSID ttn-gateway e password come da configurazione:

ssh root@ttn-gateway-wifi

Client

Connettersi all'AP con ssid ttn-gateway con password <password>

ssh root@ttn-gateway

Tramite ethernet

Non far gestire il device a NetworkManager

aggiungere in /etc/NetworkManager/conf.d/lora_gateway.conf

[keyfile]
unmanaged-devices=interface-name:eth0

se presenti altri device separare con la ","


Attivare Access Point
cd
cd git
git clone https://github.com/r-map/create_dhcp.git
cd create_dhcp
make install


systemctl enable create_dhcp
systemctl restart create_dhcp


Collegare il cavo ethernet al proprio pc configurato per una connessione dhcp:

ssh root@ttn-gateway-ethernet

Tramite server esterno

accedere a ttn.rmap.cc

ssh root@localhost -p 5022

Register gateway

Register and Login

To register as a new user, use the command ttnctl user register:

    ❯ ttnctl user register yourname your@email.org
    Password: <entering password>
    INFO Registered user

Now go to account.thethingsnetwork.org and click ttnctl access code.

You now have 5 minutes to use this code to login with ttnctl user login:

 ❯ ttnctl user login LzWtldT-VGvN56I3u3oJiU8apRJGaWJAJKbYvALJoP3
 Password: <enter password>
 INFO Successfully logged in as yourname (your@email.org)

Register new gateway

ttnctl-linux-arm gateways list
ttnctl-linux-arm gateways register <ID> EU_863_870 <lat>,<lon>


Edit

/etc/lora_pkt_fwd/local_conf.json

and change the values in configuration.

Problemi

NetworkManager

Ogni tanto NetworkManager va in crash. Temporaneamente:

/usr/lib/systemd/system/NetworkManager.service

[Service]
Restart=always
RestartSec=10

RAKWireless 831

Il reset nel concentratore RAK è connesso a GPIO0 e non a GPIO6 come da assemblaggi presentati per IMST. Quindi per il momento richiede un pacchetto diverso in attesa di modificare l'assemblaggio per IMST portando anche esso su GPIO0.

RAK fornisce nella board di adattamento a raspberry anche il gps che per funzionare richiede le seguenti modifiche:

assicurarsi che in /boot/cmdline.txt non ci sia nessun riferimento a AMA0

( rimuovere console=ttyAMA0,115200 )
groupadd -a -G dialout ttn

aggiungere in /etc/lora_pkt_fwd/local_conf.json

/* GPS configuration */ "gps_tty_path": "/dev/ttyAMA0"