basicstation: initial check-in 19188/head
authorMarcus Schref <mschref@web.de>
Wed, 7 Sep 2022 11:16:53 +0000 (13:16 +0200)
committerMarcus Schref <mschref@web.de>
Wed, 7 Sep 2022 11:17:00 +0000 (13:17 +0200)
(LoRa) Basicstation is an implementation of a LoRa packet forwarder and is
intended to be run on the host of a LoRa-based gateway. Basicstation forwards
RF packets recieved by a concentrator to a LoRaWAN network server (LNS).
It also transmits RF packets received from the LNS to one or multiple LoRa
end devices. Further information: https://lora-developers.semtech.com/build/
software/lora-basics/lora-basics-for-gateways

Signed-off-by: Marcus Schref <mschref@web.de>
net/basicstation/Makefile [new file with mode: 0644]
net/basicstation/files/etc/config/basicstation [new file with mode: 0644]
net/basicstation/files/etc/init.d/basicstation [new file with mode: 0644]
net/basicstation/patches/000-include_sys_time.patch [new file with mode: 0644]
net/basicstation/src/CMakeLists.txt [new file with mode: 0644]
net/basicstation/test.sh [new file with mode: 0644]

diff --git a/net/basicstation/Makefile b/net/basicstation/Makefile
new file mode 100644 (file)
index 0000000..a547a06
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2022 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=basicstation
+PKG_VERSION:=2.0.6
+PKG_RELEASE:=$(AUTORELEASE)
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/lorabasics/basicstation/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=7e285de94bae1174b4c3496fc3ab15fe67c72f92c0693d2320bafc654a9dfb43
+
+PKG_MAINTAINER:=Marcus Schref <mschref@tdt.de>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_DEPENDS:=sx1302_hal mbedtls
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/basicstation
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=LoRaWAN
+  TITLE:=LoRa Basic Station
+  DEPENDS:=+kmod-usb-acm
+endef
+
+define Package/basicstation/description
+  LoRa Basic Station. The LoRaWAN Gateway Software.
+endef
+
+define Package/basicstation/conffiles
+/etc/config/basicstation
+endef
+
+define Build/Prepare
+       $(call Build/Prepare/Default)
+       rm -rf $(PKG_BUILD_DIR)/deps/
+       rm -f $(PKG_BUILD_DIR)/makefile
+       rm -f $(PKG_BUILD_DIR)/makefile.s2core
+       rm -f $(PKG_BUILD_DIR)/setup.gmk
+endef
+
+define Package/basicstation/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/station $(1)/usr/bin
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/etc/config/basicstation $(1)/etc/config/basicstation
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/etc/init.d/basicstation $(1)/etc/init.d/basicstation
+endef
+
+$(eval $(call BuildPackage,basicstation))
diff --git a/net/basicstation/files/etc/config/basicstation b/net/basicstation/files/etc/config/basicstation
new file mode 100644 (file)
index 0000000..3b6a33c
--- /dev/null
@@ -0,0 +1,146 @@
+config auth 'auth'
+       option cred ''
+       option mode ''
+       option addr ''
+       option port ''
+       option token ''
+       option key ''
+       option crt ''
+       option trust ''
+
+config sx130x 'sx130x'
+       option comif ''
+       option devpath ''
+       option pps ''
+       option public ''
+       option clksrc ''
+       option radio0 ''
+       option radio1 ''
+
+config rfconf 'rfconf0'
+       option type 'SX1250'
+       option txEnable '1'
+       option freq ''
+       option antennaGain '3'
+       option rssiOffset '-215.4'
+       option useRssiTcomp 'std'
+
+config rfconf 'rfconf1'
+       option type 'SX1250'
+       option txEnable '0'
+       option freq ''
+       option antennaGain '3'
+       option rssiOffset '-215.4'
+       option useRssiTcomp 'std'
+
+config rssitcomp 'std'
+       option coeff_a '0'
+       option coeff_b '0'
+       option coeff_c '20.41'
+       option coeff_d '2162.56'
+       option coeff_e '0'
+       
+config txlut
+       option rfPower '12'
+       option paGain '0'
+       option pwrIdx '15'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '13'
+       option paGain '0'
+       option pwrIdx '16'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '14'
+       option paGain '0'
+       option pwrIdx '17'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '15'
+       option paGain '0'
+       option pwrIdx '19'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '16'
+       option paGain '0'
+       option pwrIdx '20'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '17'
+       option paGain '0'
+       option pwrIdx '22'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '18'
+       option paGain '1'
+       option pwrIdx '1'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '19'
+       option paGain '1'
+       option pwrIdx '2'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '20'
+       option paGain '1'
+       option pwrIdx '3'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '21'
+       option paGain '1'
+       option pwrIdx '4'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '22'
+       option paGain '1'
+       option pwrIdx '5'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '23'
+       option paGain '1'
+       option pwrIdx '6'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '24'
+       option paGain '1'
+       option pwrIdx '7'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '25'
+       option paGain '1'
+       option pwrIdx '9'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '26'
+       option paGain '1'
+       option pwrIdx '11'
+       list usedBy 'rfconf0'
+
+config txlut
+       option rfPower '27'
+       option paGain '1'
+       option pwrIdx '14'
+       list usedBy 'rfconf0'
+
+config station 'station'
+       option idGenIf ''
+       option routerid ''
+       option stationid ''
+       option logFile ''
+       option logLevel ''
+       option logSize ''
+       option logRotate ''
diff --git a/net/basicstation/files/etc/init.d/basicstation b/net/basicstation/files/etc/init.d/basicstation
new file mode 100644 (file)
index 0000000..638de35
--- /dev/null
@@ -0,0 +1,254 @@
+#!/bin/sh /etc/rc.common
+#
+# Copyright (C) 2022 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See https://www.gnu.org/licenses/gpl-2.0.txt for more information.
+
+START=85
+STOP=25
+
+USE_PROCD=1
+
+#radioconf
+DEFAULT_COMIF='usb'
+DEFAULT_DEVPATH='/dev/ttyACM0'
+DEFAULT_PPS=0
+DEFAULT_PUBLIC=1
+DEFAULT_CLKSRC=0
+DEFAULT_RADIO_0='rfconf0'
+DEFAULT_RADIO_1='rfconf1'
+
+#rfconf
+DEFAULT_TYPE='SX1250'
+DEFAULT_TX_ENABLE=0
+DEFAULT_FREQ=0
+DEFAULT_RSSI_OFFSET=0
+DEFAULT_ANTENNA_GAIN=0
+DEFAULT_RSSI_TCOMP='std'
+
+#rssi tcomp
+DEFAULT_RSSI_TCOMP_A=0
+DEFAULT_RSSI_TCOMP_B=0
+DEFAULT_RSSI_TCOMP_C=20.41
+DEFAULT_RSSI_TCOMP_D=2162.56
+DEFAULT_RSSI_TCOMP_E=0
+
+#tx gain lut
+DEFAULT_RF_POWER=0
+DEFAULT_PA_GAIN=0
+DEFAULT_PWR_IDX=0
+
+#station
+DEFAULT_RADIO_INIT=''
+DEFAULT_ID_GEN_IF='eth0'
+DEFAULT_ROUTER_ID='/sys/class/net/eth0/address'
+DEFAULT_LOG_FILE='/tmp/basicstation/log'
+DEFAULT_LOG_LEVEL='DEBUG'
+DEFAULT_LOG_SIZE=1
+DEFAULT_LOG_ROTATE=1
+
+#auth
+DEFAULT_CREDENTIALS='tc'
+DEFAULT_MODE='no'
+
+parse_txlut() {
+       local section="$1"
+       local buffer
+
+       config_get buffer "$section" usedBy
+
+       if [[ "$buffer" == *"$2"* ]]; then
+               json_add_object
+
+               config_get buffer "$section" rfPower "$DEFAULT_RF_POWER"
+               json_add_int 'rf_power' "$buffer"
+               config_get_bool buffer "$section" paGain "$DEFAULT_PA_GAIN"
+               json_add_int 'pa_gain' "$buffer"
+               config_get buffer "$section" pwrIdx "$DEFAULT_PWR_IDX"
+               json_add_int 'pwr_idx' "$buffer"
+
+               json_close_object
+       fi
+}
+
+parse_rssitcomp() {
+       local section="$1"
+       local buffer
+
+       if [ "$section" = "$2" ]; then
+               json_add_object 'rssi_tcomp'
+
+               config_get buffer "$section" coeff_a "$DEFAULT_RSSI_TCOMP_A"
+               json_add_double 'coeff_a' "$buffer"
+               config_get buffer "$section" coeff_b "$DEFAULT_RSSI_TCOMP_B"
+               json_add_double 'coeff_b' "$buffer"
+               config_get buffer "$section" coeff_c "$DEFAULT_RSSI_TCOMP_C"
+               json_add_double 'coeff_c' "$buffer"
+               config_get buffer "$section" coeff_d "$DEFAULT_RSSI_TCOMP_D"
+               json_add_double 'coeff_d' "$buffer"
+               config_get buffer "$section" coeff_e "$DEFAULT_RSSI_TCOMP_E"
+               json_add_double 'coeff_e' "$buffer"
+
+               json_close_object
+       fi
+}
+
+parse_rfconf() {
+       local section="$1"
+       local buffer
+
+       if [ "$section" = "$2" ]; then
+               json_add_object "radio_"$3""
+
+               config_get buffer "$section" type "$DEFAULT_TYPE"
+               json_add_string 'type' "$buffer"
+               config_get buffer "$section" freq "$DEFAULT_FREQ"
+               json_add_int 'freq' "$buffer"
+               config_get buffer "$section" antennaGain "$DEFAULT_ANTENNA_GAIN"
+               json_add_int 'antenna_gain' "$buffer"
+               config_get buffer "$section" rssiOffset "$DEFAULT_RSSI_OFFSET"
+               json_add_double 'rssi_offset' "$buffer"
+               config_get buffer "$section" useRssiTcomp "$DEFAULT_RSSI_TCOMP"
+               config_foreach parse_rssitcomp rssitcomp "$buffer"
+               config_get_bool buffer "$section" txEnable "$DEFAULT_TX_ENABLE"
+               json_add_boolean 'tx_enable' "$buffer"
+
+               if [ "$buffer" -eq 1 ]; then
+                       json_add_array 'tx_gain_lut'
+                       config_foreach parse_txlut txlut "$section"
+                       json_close_array
+               fi
+
+               json_close_object
+       fi
+}
+
+parse_sx130x() {
+       local section="$1"
+       local comif
+       local devpath
+       local buffer
+
+       json_add_object 'radio_conf'
+
+       config_get comif "$section" comif "$DEFAULT_COMIF"
+       config_get devpath "$section" devpath "$DEFAULT_DEVPATH"
+       json_add_string 'device' ""$comif":"$devpath""
+       config_get_bool buffer "$section" pps "$DEFAULT_PPS"
+       json_add_boolean 'pps' "$buffer"
+       config_get_bool buffer "$section" public "$DEFAULT_PUBLIC"
+       json_add_boolean 'lorawan_public' "$buffer"
+       config_get buffer "$section" clksrc "$DEFAULT_CLKSRC"
+       json_add_int 'clksrc' "$buffer"
+       json_add_boolean 'full_duplex' 0
+       config_get buffer "$section" radio0 "$DEFAULT_RADIO_0"
+       config_foreach parse_rfconf rfconf "$buffer" 0
+       config_get buffer "$section" radio1 "$DEFAULT_RADIO_1"
+       config_foreach parse_rfconf rfconf "$buffer" 1
+
+       json_close_object
+}
+
+parse_station() {
+       local section="$1"
+       local buffer
+       local mac
+
+       config_get buffer "$section" idGenIf "$DEFAULT_ID_GEN_IF"
+       mac=$(head -n 1 /sys/class/net/"$buffer"/address)
+       uci_set basicstation "$section" stationid "${mac::8}:ff:fe:${mac:9:8}"
+       uci_commit basicstation
+
+       json_add_object 'station_conf'
+
+       config_get buffer "$section" routerid "$DEFAULT_ROUTER_ID"
+       json_add_string 'routerid' "$buffer"
+       config_get buffer "$section" radioInit "$DEFAULT_RADIO_INIT"
+       json_add_string 'radio_init' "$buffer"
+       config_get buffer "$section" logFile "$DEFAULT_LOG_FILE"
+       json_add_string 'log_file' "$buffer"
+       config_get buffer "$section" logLevel "$DEFAULT_LOG_LEVEL"
+       json_add_string 'log_level' "$buffer"
+       config_get buffer "$section" logSize "$DEFAULT_LOG_SIZE"
+       json_add_int 'log_size' $(( 1000000*buffer ))
+       config_get buffer "$section" logRotate "$DEFAULT_LOG_ROTATE"
+       json_add_int 'log_rotate' "$buffer"
+
+       json_close_object
+}
+
+parse_auth() {
+       local section="$1"
+       local cred
+       local mode
+       local addr
+       local port
+       local uri
+       local buffer
+
+       config_get cred "$section" cred "$DEFAULT_CREDENTIALS"
+       config_get mode "$section" mode "$DEFAULT_MODE"
+       config_get addr "$section" addr
+       config_get port "$section" port
+
+       if [ "$mode" != 'no' ]; then
+               config_get buffer "$section" trust
+               [ -f "$buffer" ] && cp "$buffer" /tmp/basicstation/"$cred".trust
+               if [ "$mode" = 'serverAndClient' ]; then
+                       config_get buffer "$section" key
+                       echo "$buffer" > /tmp/basicstation/"$cred".key
+                       config_get buffer "$section" crt
+                       [ -f "$buffer" ] && cp "$buffer" /tmp/basicstation/"$cred".crt
+               elif [ "$mode" = 'serverAndClientToken' ]; then
+                       config_get buffer "$section" token
+                       echo "$buffer" > /tmp/basicstation/"$cred".key
+               fi
+               if [ "$cred" = "tc" ]; then
+                       uri="wss://${addr}:${port}"
+               else
+                       uri="https://${addr}:${port}"
+               fi
+       else
+               if [ "$cred" = "tc" ]; then
+                       uri="ws://${addr}:${port}"
+               else
+                       uri="http://${addr}:${port}"
+               fi
+       fi
+
+       echo "$uri" > /tmp/basicstation/"$cred".uri
+}
+
+process_config() {
+       . /usr/share/libubox/jshn.sh
+       json_init
+
+       config_load basicstation
+       config_foreach parse_sx130x sx130x
+       config_foreach parse_station station
+       json_dump -i > /tmp/basicstation/station.conf
+       config_foreach parse_auth auth
+}
+
+service_triggers() {
+       procd_add_reload_trigger "basicstation"
+}
+
+start_service() {
+       rm -rf /tmp/basicstation/
+       mkdir -p /tmp/basicstation/
+
+       process_config
+
+       procd_open_instance
+       procd_set_param command /usr/bin/station
+       procd_append_param command --home /tmp/basicstation/
+       procd_append_param command --force
+       procd_set_param respawn
+       procd_close_instance
+}
+
+reload_service() {
+       restart "$@"
+}
diff --git a/net/basicstation/patches/000-include_sys_time.patch b/net/basicstation/patches/000-include_sys_time.patch
new file mode 100644 (file)
index 0000000..f8571d1
--- /dev/null
@@ -0,0 +1,24 @@
+From ca1eb77bf89697e1bacbb21ed7aae8b5134a7bf5 Mon Sep 17 00:00:00 2001
+From: Marcus Schref <mschref@web.de>
+Date: Mon, 22 Aug 2022 10:13:52 +0200
+Subject: [PATCH] basicstation: include sys/time.h
+
+Change time.h include directory to add compatibility with musl and fix
+compilation error
+
+Signed-off-by: Marcus Schref <mschref@web.de>
+---
+ src/aio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/src/aio.c
++++ b/src/aio.c
+@@ -27,7 +27,7 @@
+  */
+ #include <unistd.h>
+-#include <time.h>
++#include <sys/time.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include "rt.h"
diff --git a/net/basicstation/src/CMakeLists.txt b/net/basicstation/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8c1dfd4
--- /dev/null
@@ -0,0 +1,86 @@
+cmake_minimum_required(VERSION 3.18.4)
+project(basicstation)
+
+add_compile_definitions(CFG_linux)
+add_compile_definitions(CFG_lgw1)
+add_compile_definitions(CFG_sx1302)
+add_compile_definitions(CFG_ral_lgw)
+add_compile_definitions(CFG_no_leds)
+add_compile_definitions(CFG_argp)
+add_compile_definitions(CFG_platform="linux")
+add_compile_definitions(CFG_bdate=${PKG_SOURCE_DATE})
+file(STRINGS "VERSION.txt" VERSION_NUMBER)
+add_compile_definitions(CFG_version="${VERSION_NUMBER}")
+
+
+include_directories(src)
+include_directories(src-linux)
+
+find_path(SX1302_HAL_INCLUDE_DIR NAMES lgw/loragw_hal.h)
+find_path(MBEDTLS_INCLUDE_DIR NAMES mbedtls/x509.h)
+find_library(SX1302_HAL_LIBRARY NAMES libloragw.a PATH /usr/lib/)
+find_library(TINYMT32_LIBRARY NAMES libtinymt32.a PATH /usr/lib/)
+find_library(MBEDTLS_LIBRARY NAMES libmbedtls.a PATH /usr/lib/)
+find_library(MBEDCRYPTO_LIBRARY NAMES libmbedcrypto.a PATH /usr/lib/)
+find_library(MBEDX509_LIBRARY NAMES libmbedx509.a PATH /usr/lib/)
+
+set(basicstation_SOURCE_FILES
+       src/aio.c
+       src/argp.c
+       src/crc32.c
+       src/cups.c
+       src/flashsim.c
+       src/fs.c
+       src/genkwcrcs.c
+       src/lgwsim.c
+       src/log.c
+       src/lora.c
+       src/net.c
+       src/ral.c
+       src/ral_lgw.c
+       src/ral_lgw2.c
+       src/rt.c
+       src/s2conf.c
+       src/s2e.c
+       src/selftest_fs.c
+       src/selftest_lora.c
+       src/selftest_rt.c
+       src/selftest_ujdec.c
+       src/selftest_ujenc.c
+       src/selftest_xprintf.c
+       src/selftest_xq.c
+       src/selftests.c
+       src/sx1301v2conf.c
+       src/sx130xconf.c
+       src/sys.c
+       src/sys.h
+       src/tc.c
+       src/timesync.c
+       src/tls.c
+       src/uj.c
+       src/web.c
+       src/xq.c
+       src-linux/cmdfifo.c
+       src-linux/commands.c
+       src-linux/gps.c
+       src-linux/leds.c
+       src-linux/ral_master.c
+       src-linux/ral_slave.c
+       src-linux/rmtsh.c
+       src-linux/sys_linux.c
+       src-linux/sys_log.c
+       src-linux/web_linux.c)
+
+add_library(s2core ${basicstation_SOURCE_FILES})
+target_include_directories(s2core PRIVATE ${SX1302_HAL_INCLUDE_DIR})
+target_include_directories(s2core PRIVATE ${MBEDTLS_INCLUDE_DIR})
+target_link_libraries(s2core ${SX1302_HAL_LIBRARY} ${TINYMT32_LIBRARY} m)
+target_link_libraries(s2core ${MBEDTLS_LIBRARY})
+target_link_libraries(s2core ${MBEDCRYPTO_LIBRARY})
+target_link_libraries(s2core ${MBEDX509_LIBRARY})
+
+add_executable(station src-linux/station_main.c)
+
+target_link_libraries(station s2core)
+
+install(TARGETS station RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/net/basicstation/test.sh b/net/basicstation/test.sh
new file mode 100644 (file)
index 0000000..ca28b50
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+station --version 2>&1 | grep "$2"