basicstation: initial check-in

(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>
This commit is contained in:
Marcus Schref 2022-09-07 13:16:53 +02:00
parent deb8921629
commit b7d466040c
6 changed files with 573 additions and 0 deletions

60
net/basicstation/Makefile Normal file
View file

@ -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))

View file

@ -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 ''

View file

@ -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 "$@"
}

View file

@ -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"

View file

@ -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})

3
net/basicstation/test.sh Normal file
View file

@ -0,0 +1,3 @@
#!/bin/sh
station --version 2>&1 | grep "$2"