diff --git a/net/basicstation/Makefile b/net/basicstation/Makefile new file mode 100644 index 00000000000000..4c3e57039f9826 --- /dev/null +++ b/net/basicstation/Makefile @@ -0,0 +1,60 @@ +# +# Copyright (C) 2022 TDT AG +# +# 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 +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_BIN) ./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 index 00000000000000..3b6a33c7f0e666 --- /dev/null +++ b/net/basicstation/files/etc/config/basicstation @@ -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 index 00000000000000..638de3533cecb3 --- /dev/null +++ b/net/basicstation/files/etc/init.d/basicstation @@ -0,0 +1,254 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2022 TDT AG +# +# 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 index 00000000000000..f8571d1c0e742d --- /dev/null +++ b/net/basicstation/patches/000-include_sys_time.patch @@ -0,0 +1,24 @@ +From ca1eb77bf89697e1bacbb21ed7aae8b5134a7bf5 Mon Sep 17 00:00:00 2001 +From: Marcus Schref +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 +--- + src/aio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/src/aio.c ++++ b/src/aio.c +@@ -27,7 +27,7 @@ + */ + + #include +-#include ++#include + #include + #include + #include "rt.h" diff --git a/net/basicstation/src/CMakeLists.txt b/net/basicstation/src/CMakeLists.txt new file mode 100644 index 00000000000000..8c1dfd468bfbf1 --- /dev/null +++ b/net/basicstation/src/CMakeLists.txt @@ -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 index 00000000000000..ca28b5013f9fb4 --- /dev/null +++ b/net/basicstation/test.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +station --version 2>&1 | grep "$2"