diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ea515a7c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# IDE +.vscode + +deps/.DS_Store +.DS_Store diff --git a/Dockerfile b/Dockerfile index 1926cac6..5b81934c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,3 +30,4 @@ RUN sudo apt-get install --no-install-recommends -yq \ RUN pip3 install aiohttp websockets + diff --git a/Dockerfile.template b/Dockerfile.template new file mode 100644 index 00000000..af638d48 --- /dev/null +++ b/Dockerfile.template @@ -0,0 +1,27 @@ +FROM balenalib/%%BALENA_MACHINE_NAME%%-debian:buster-build as builder +# Install build tools and remove layer cache afterwards + + +# Switch to working directory for our app +WORKDIR /usr/src/app + +# Copy all the source code in. +COPY . . + +# Compile our source code +RUN make platform=rpi variant=std arch=%%BALENA_ARCH%% +RUN make platform=corecell variant=std arch=%%BALENA_ARCH%% + + +FROM balenalib/%%BALENA_MACHINE_NAME%%-debian:buster + +RUN install_packages jq + +WORKDIR /usr/src/app + +COPY --from=builder /usr/src/app/ ./ + +COPY start* ./ + +# Launch our binary on container startup. +CMD ["bash", "start.sh"] diff --git a/README.md b/README.md index 78d8970e..b81b3457 100644 --- a/README.md +++ b/README.md @@ -1,166 +1,210 @@ -[![Build Status](https://travis-ci.com/lorabasics/basicstation.svg?branch=master)](https://travis-ci.com/lorabasics/basicstation) +# LoRa Basics™ Station using balena.io with sx1301, sx1302 and sx1303 LoRa concentrators -# LoRa Basics™ Station +## This project is deprecated! You can see the balena basicstation updated here -[Basic Station](https://doc.sm.tc/station) is a LoRaWAN Gateway implementation, including features like +[https://github.com/xoseperez/basicstation](https://github.com/xoseperez/basicstation-docker) -* **Ready for LoRaWAN Classes A, B, and C** -* **Unified Radio Abstraction Layer supporting Concentrator Reference Designs [v1.5](https://doc.sm.tc/station/gw_v1.5.html), [v2](https://doc.sm.tc/station/gw_v2.html) and [Corecell](https://doc.sm.tc/station/gw_corecell.html)** +--- -* **Powerful Backend Protocols** (read [here](https://doc.sm.tc/station/tcproto.html) and [here](https://doc.sm.tc/station/cupsproto.html)) - - Centralized update and configuration management - - Centralized channel-plan management - - Centralized time synchronization and transfer - - Various authentication schemes (client certificate, auth tokens) - - Remote interactive shell +This project deploys a LoRaWAN gateway with Basics™ Station Packet Forward protocol with balena. It runs on a Raspberry Pi (3/4) or balenaFin with sx1301, sx1302 and sx1303 SPI LoRa concentrators (e.g. RAK833, RAK2245, RAK2287, RAK5146, Seeed WM1302 and IMST iC880a among others). -* **Lean Design** - - No external software dependencies (except mbedTLS and libloragw/-v2) - - Portable C code, no C++, dependent only on GNU libc - - Easily portable to Linux-based gateways and embedded systems - - No dependency on local time keeping - - No need for incoming connections -## Documentation +## Introduction -The full documentation is available at [https://doc.sm.tc/station](https://doc.sm.tc/station). +Deploy a The Things Stack (TTS v3) LoRaWAN gateway running the Basics™ Station Semtech Packet Forward protocol. We are using balena.io and RAK to reduce fricition for the LoRa gateway fleet owners. This project has been tested with The Things Network (TTN v2), The Things Stack (TTS v3) and The Things Industries (TTI) as well. -### High Level Architecture +The Basics™ Station protocol enables the LoRa gateways with a reliable and secure communication between the gateways and the cloud and it is becoming the standard Packet Forward protocol used by most of the LoRaWAN operators. -![High Level Station Architecture](https://doc.sm.tc/station/_images/architecture.png) -## Prerequisites +## Getting started -Building the Station binary from source, requires +### Hardware -* gcc (C11 with GNU extensions) -* GNU make -* git -* bash +* Raspberry Pi 0, 3/4 or [balenaFin](https://www.balena.io/fin/) +* SD card in case of the RPi 0/3/4 -## First Steps +#### LoRa Concentrators (SPI) -The following is a three-step quick start guide on how to build and run Station. It uses a Raspberry Pi as host platform and assumes a Concentrator Reference Design 1.5 compatible radio board connected via SPI. In this example the build process is done on the target platform itself (the make environment also supports cross compilation in which case the toolchain is expected in `~/toolchain-$platform` - see [setup.gmk](setup.gmk)). +Disclaimer: At the moment the basicstation project is not compatible with USB LoRa concentrators. Contributions open :) -#### Step 1: Cloning the Station Repository +* SX1301 +> * [IMST iC880a](https://shop.imst.de/wireless-modules/lora-products/8/ic880a-spi-lorawan-concentrator-868-mhz) +> * [RAK 2245 pi hat](https://store.rakwireless.com/products/rak2245-pi-hat) +> * RAK833 -``` sourceCode -git clone https://github.com/lorabasics/basicstation.git -``` +* SX1302 +> * [RAK 2287 Concentrator](https://store.rakwireless.com/products/rak2287-lpwan-gateway-concentrator-module) with [RAK 2287 Pi Hat](https://store.rakwireless.com/products/rak2287-pi-hat) +> * [Seeed WM1302](https://www.seeedstudio.com/WM1302-LoRaWAN-Gateway-Module-SPI-EU868-p-4889.html) with the Pi Hat (this model is compatible with the RAK2287 Pi Hat as well). -#### Step 2: Compiling the Station Binary +* SX1303 +> * [RAK 5146](https://store.rakwireless.com/products/wislink-lpwan-concentrator-rak5146) with RAK2287 Pi Hat. -``` sourceCode -cd basicstation -make platform=rpi variant=std -``` -The build process consists of the following steps: +### Software -* Fetch and build dependencies, namely [mbedTLS](https://github.com/ARMmbed/mbedtls) and [libloragw](https://github.com/Lora-net/lora_gateway) -* Setup build environment within subdirectory `build-$platform-$variant/` -* Compile station source files into executable `build-$platform-$variant/bin/station` +* A The Things Stack V3 account [here](https://ttc.eu1.cloud.thethings.industries/console/) +* A balenaCloud account ([sign up here](https://dashboard.balena-cloud.com/)) +* [balenaEtcher](https://balena.io/etcher) -#### Step 3: Running the Example Configuration on a Raspberry Pi +Once all of this is ready, you are able to deploy this repository following instructions below. -``` sourceCode -cd examples/live-s2.sm.tc -RADIODEV=/dev/spidev0.0 ../../build-rpi-std/bin/station -``` +## Deploy the code -**Note:** The SPI device for the radio MAY be passed as an environment variable using `RADIODEV`. +### Via [Balena Deploy](https://www.balena.io/docs/learn/deploy/deploy-with-balena-button/) -The example configuration connects to a public test server [s2.sm.tc](wss://s2.sm.tc) through which Station fetches all required credentials and a channel plan matching the region as determined from the IP address of the gateway. Provided there are active LoRa devices in proximity, received LoRa frames are printed in the log output on `stderr`. +Running this project is as simple as deploying it to a balenaCloud application. You can do it in just one click by using the button below: -## Instruction for Supported Platfroms +[![](https://www.balena.io/deploy.png)](https://dashboard.balena-cloud.com/deploy?repoUrl=https://github.com/balenalabs/basicstation) -#### Corecell Platform (Raspberry Pi as HOST + [SX1302CxxxxGW Concentrator](https://www.semtech.com/products/wireless-rf/lora-gateways/sx1302cxxxgw1)) +Follow instructions, click Add a Device and flash an SD card with that OS image dowloaded from balenaCloud. Enjoy the magic 🌟Over-The-Air🌟! -##### Compile and Running the Example -``` sourceCode -cd basicstation -make platform=corecell variant=std -cd examples/corecell -./start-station.sh -l ./lns-ttn -``` +### Via [Balena-Cli](https://www.balena.io/docs/reference/balena-cli/) -This example configuration for Corecell connects to [The Things Network](https://www.thethingsnetwork.org/) public LNS. The example [station.conf](station.conf) file holds the required radio configurations and station fetches the channel plan from the configured LNS url ([tc.uri](tc.uri)). +If you are a balena CLI expert, feel free to use balena CLI. -#### PicoCell Gateway (Linux OS as HOST + [SX1308 USB Reference design](https://www.semtech.com/products/wireless-rf/lora-gateways/sx1308p868gw)) +- Sign up on [balena.io](https://dashboard.balena.io/signup) +- Create a new application on balenaCloud. +- Clone this repository to your local workspace. +- Using [Balena CLI](https://www.balena.io/docs/reference/cli/), push the code with `balena push ` +- See the magic happening, your device is getting updated 🌟Over-The-Air🌟! -##### Compile and Running the Example +## Configure the Gateway -``` sourceCode -cd basicstation -make platform=linuxpico variant=std -cd examples/live-s2.sm.tc -RADIODEV=/dev/ttyACM0 ../../build-linuxpico-std/bin/station -``` +### Define your MODEL -**Note:** The serial device for the PicoCell MAY be passed as an environment variable using `RADIODEV`. +The model is defined depending on the version of the LoRa concentrator: ```SX1301```, ```SX1302``` and ```SX1303```. -## Next Steps +In case that your LoRa concentrator is a ```RAK2287``` it is using ```SX1302```. If the concentrator is the ```RAK2245``` or ```iC880a``` it uses the ```SX1301```. It's important to change the balenaCloud Device Variable with the correct ```MODEL```. The default ```MODEL``` on the balena Application is the ```SX1301```. -Next, +1. Go to balenaCloud dashboard and get into your LoRa gateway device site. +2. Click "Device Variables" button on the left menu and change the ```MODEL``` variable to ```SX1302``` if needed. -* consult the help menu of Station via `station --help`, -* inspect the `station.conf` and `cups-boot.*` [example configuration files](/examples/live-s2.sm.tc), -* tune your local [configuration](https://doc.sm.tc/station/conf.html), -* learn how to [compile Station](https://doc.sm.tc/station/compile.html) for your target platform. +That enables a fleet of LoRa gateways with both (e.g.) ```RAK2245``` and ```RAK2287``` together under the same app. -Check out the other examples: +### Define your REGION and TTN STACK VERSION -* [Simulation Example](/examples/simulation) - An introduction to the simulation environment. -* [CUPS Example](/examples/cups) - Demonstration of the CUPS protocol within the simulation environment. -* [Station to Pkfwd Protocol Bridge Example](/examples/station2pkfwd) - Connect Basic Station to LNS supporting the legacy protocol. +From now it's important to facilitate the ```TTN_STACK_VERSION``` that you are going to use: ```3``` (The Things Stack v3) or ```2``` (The Things Network or TTN V2). The default variable is set into ```3```(V3). -## Usage +Before starting, also check the ```TTN_REGION```. It needs to be changed if your region is not Europe. In case you use version 3, the European version is ```eu1``` by default. Check [here](https://www.thethingsnetwork.org/docs/lorawan/frequencies-by-country.html) the LoRa frequencies by country. -The Station binary accepts the following command-line options: +With these variables ```TTN_REGION``` and ```TTN_STACK_VERSION``` the ```TC_URI``` will be generated automatically. In case that you want to point to another specific ```TC_URI```, feel free to add this Device Variable on the balenaCloud. -``` -Usage: station [OPTION...] +### Get the EUI of the LoRa Gateway - -d, --daemon First check if another process is still alive. If - so do nothing and exit. Otherwise fork a worker - process to operate the radios and network - protocols. If the subprocess died respawn it with - an appropriate back off. - -f, --force If a station process is already running, kill it - before continuing with requested operation mode. - -h, --home=DIR Home directory for configuration files. Default is - the current working directory. Overrides - environment STATION_DIR. - -i, --radio-init=cmd Program/script to run before reinitializing radio - hardware. By default nothing is being executed. - Overrides environment STATION_RADIOINIT. - -k, --kill Kill a currently running station process. - -l, --log-level=LVL|0..7 Set a log level LVL=#loglvls# or use a numeric - value. Overrides environment STATION_LOGLEVEL. - -L, --log-file=FILE[,SIZE[,ROT]] - Write log entries to FILE. If FILE is '-' then - write to stderr. Optionally followed by a max file - SIZE and a number of rotation files. If ROT is 0 - then keep only FILE. If ROT is 1 then keep one - more old log file around. Overrides environment - STATION_LOGFILE. - -N, --no-tc Do not connect to a LNS. Only run CUPS - functionality. - -p, --params Print current parameter settings. - -t, --temp=DIR Temp directory for frequently written files. - Default is /tmp. Overrides environment - STATION_TEMPDIR. - -x, --eui-prefix=id6 Turn MAC address into EUI by adding this prefix. - If the argument has value ff:fe00:0 then the EUI - is formed by inserting FFFE in the middle. If - absent use MAC or routerid as is. Overrides - environment STATION_EUIPREFIX. - -?, --help Give this help list - --usage Give a short usage message - -v, --version Print station version. - -Mandatory or optional arguments to long options are also mandatory or optional -for any corresponding short options. -``` +The LoRa gateways are manufactured with a unique 64 bits (8 bytes) identifier, called EUI, which can be used to register the gateway on The Things Network and The Things Stack. To get the EUI from your board it’s important to know the Ethernet MAC address of it (this is not going to work if your device does not have Ethernet port). + +The ```EUI``` will be the Ethernet mac address (6 bytes), which is unique, expanded with 2 more bytes (FFFE). This is a standard way to increment the MAC address from 6 to 8 bytes. + +To get the ```EUI```, copy the TAG of the device which will be generated automatically when the device gets provisioned on balenaCloud for first time. Be careful when you copy the tag, as other characters will be copied. + +If that does not work, go to the terminal box and click "Select a target", then “HostOS”. Once you are inside the shell, type: + +```cat /sys/class/net/eth0/address | sed -r 's/[:]+//g' | sed -e 's#\(.\{6\}\)\(.*\)#\1fffe\2#g' ``` + +Copy the result and you are ready to register your gateway with this EUI. + + +### Configure your The Things Stack gateway (V3) + +1. Sign up at [The Things Stack console](https://ttc.eu1.cloud.thethings.industries/console/). +2. Click "Go to Gateways" icon. +3. Click the "Add gateway" button. +4. Introduce the data for the gateway. +5. Paste the EUI from the balenaCloud tags. +6. Complete the form and click Register gateway. +7. Once the gateway is created, click "API keys" link. +8. Click "Add API key" button. +9. Select "Grant individual rights" and then "Link as Gateway to a Gateway Server for traffic exchange ..." and then click "Create API key". +10. Copy the API key generated. and bring it to balenaCloud as ```TC_KEY```. + +### Configure your The Things Network gateway (V2) + +1. Sign up at [The Things Network console](https://console.thethingsnetwork.org/). +2. Click Gateways button. +3. Click the "Register gateway" link. +4. Check “I’m using the legacy packet forwarder” checkbox. +5. Paste the EUI from the balenaCloud tag or the Ethernet mac address of the board (calculated above) +6. Complete the form and click Register gateway. +7. Copy the Key generated on the gateway page. + + +### Balena LoRa Basics Station Service Variables + +Once successfully registered: + +1. Go to balenaCloud dashboard and get into your LoRa gateway device site. +2. Click "Device Variables" button on the left menu and add these variables. + +Alternativelly, you can also set any of them at application level if you want it to apply to all devices in you application. + + +#### Common Variables + +Variable Name | Value | Description | Default +------------ | ------------- | ------------- | ------------- +**`GW_GPS`** | `STRING` | Enables GPS | true or false +**`GW_RESET_PIN`** | `INT` | Pin number that resets (Raspberry Pi header number) | 11 +**`GW_RESET_GPIO`** | `INT` | GPIO number that resets (Broadcom pin number, if not defined, it's calculated based on the GW_RESET_PIN) | 17 +**`TTN_STACK_VERSION`** | `INT` | If using TTN, version of the stack. It can be either 2 (TTNv2) or 3 (TTS) | 3 +**`TTN_REGION`** | `STRING` | Region of the TTN server to use | ```eu1``` (when using TTN v2 use ```eu```) +**`TC_TRUST`** | `STRING` | Certificate for the server | Automatically retrieved from LetsEncryt based on the `TTN_STACK_VERSION` value +**`MODEL`** | `STRING` | ```SX1301``` or ```SX1302``` | ```SX1301``` +**`TC_URI`** | `STRING` | basics station TC URI to get connected. | +**`EUI_ADDRESS`** | `STRING` | In case you use Raspberry Pi Zero without `eth0` you can use this to generate the `EUI` from `wlan0` instead of another network interface. You will need to add `wlan0` | + + +#### The Things Stack (TTS) Specific Variables (V3) + +Remember to generate an API Key and copy it. It will be the ```TC_KEY```. + +The `TC_URI` and `TC_TRUST` values are automatically populated to use ```wss://eu1.cloud.thethings.network:8887``` if you set `TTN_STACK_VERSION` to 3.If your region is not EU you can set it using ```TTN_REGION```. At the moment there is only one server avalable is ```eu1```. + +Variable Name | Value | Description | Default +------------ | ------------- | ------------- | ------------- +**`TC_KEY`** | `STRING` | Unique TTN Gateway Key | (Key pasted from TTN console) + + +#### (Deprecated) The Things Network (TTNv2) Specific Variables (V2) + +Remember to copy the The Things Network gateway KEY and ID to configure your board variables on balenaCloud. + +The `GW_ID`and `GW_KEY` variables have been generated automatically when the Application has been created with the Deploy with Balena button. Replace the values with the KEY and ID from the TTN console. + +The `TC_URI` and `TC_TRUST` values are automatically populated to use ```wss://lns.eu.thethings.network:443``` if you set `TTN_STACK_VERSION` to 2. If your region is not EU you can set it using ```TTN_REGION```, Possible values are ```eu```, ```us```, ```in``` and ```au```. + +Variable Name | Value | Description | Default +------------ | ------------- | ------------- | ------------- +**`GW_ID`** | `STRING` | TTN Gateway EUI | (EUI) +**`GW_KEY`** | `STRING` | Unique TTN Gateway Key | (Key pasted from TTN console) + + +At this moment your LoRaWAN gateway should be up and running. Check on the TTN or TTS console if it shows the connected status. + + +## Troubleshoothing + +It's possible that on the TTN Console the gateway appears as Not connected if it's not receiving any LoRa message. Sometimes the websockets connection among the LoRa Gateway and the server can get broken. However a new LoRa package will re-open the websocket between the Gateway and TTN or TTI. This issue should be solved with the TTN v3. + +Feel free to introduce issues on this repo and contribute with solutions. + + +## TTNv2 to TTS migration + +Initial state: one of more devices connected to TTNv2 stack (The Things Network). + +Proposed procedure: + +1. Create the gateways at TTS using the very same Gateway ID (Gateway EUI) +2. Create a `TC_KEY` variable on each device with the TTN Gateway Key pasted from the TTI console. +3. Set the `TTN_STACK_VERSION` variable to 3, either at application level or per device + +Now you can move them from TTS to TTNv2 back and forth (using the `TTN_STACK_VERSION` variable) as you wish as long as the gateways are defined on both platforms and the `TC_KEY` and `GW_KEY` do not change. + + +## Attribution + +- This is an adaptation of the [Semtech Basics Station repository](https://github.com/lorabasics/basicstation). Documentation [here](https://doc.sm.tc/station). +- This is in part working thanks of the work of Jose Marcelino from RAK Wireless, Xose Pérez from Allwize and Marc Pous from balena.io. +- This is in part based on excellent work done by Rahul Thakoor from the Balena.io Hardware Hackers team. diff --git a/balena.yml b/balena.yml new file mode 100644 index 00000000..318bdd9e --- /dev/null +++ b/balena.yml @@ -0,0 +1,39 @@ +name: The Things Stack Gateway +type: sw.application +description: >- + Deploys the The Things Stack LoRaWAN gateway with Basics Station + Packet Forward protocol on SX1301 or SX1302 LoRa concentrators. +joinable: false +post-provisioning: >- + ## Usage instructions + + Fork this fleet and deploy the project on a balenaCloud application. Once the project released on a device, you'll need to get the EUI of the device and create a gateway on The Things Stack (V3). + + For detailed instructions on how to use configure your LoRaWAN gteway check out the [readme here](https://github.com/balenalabs/basicstation). +assets: + repository: + type: blob.asset + data: + url: 'https://github.com/balenalabs/basicstation' + logo: + type: blob.asset + data: + url: >- + https://raw.githubusercontent.com/balenalabs/basicstation/master/logo.png +data: + applicationEnvironmentVariables: + - GW_GPS: false + - GW_RESET_PIN: 11 + - GW_RESET_GPIO: 17 + - MODEL: SX1301 + - TTN_STACK_VERSION: 3 + - TTN_REGION: eu1 + - GW_ID: 0 + - GW_KEY: 0 + - TC_KEY: 0 + defaultDeviceType: raspberrypi3 + supportedDeviceTypes: + - raspberrypi3 + - raspberrypi3-64 + - raspberrypi4-64 + - fincm3 diff --git a/deps/lgw/v5.0.1-kerlink.patch b/deps/lgw/v5.0.1-kerlink.patch index 8a2281b6..2e9a122f 100644 --- a/deps/lgw/v5.0.1-kerlink.patch +++ b/deps/lgw/v5.0.1-kerlink.patch @@ -125,7 +125,8 @@ index c01ed1c..0e2b64c 100644 @@ -54,7 +54,7 @@ Maintainer: Sylvain Miermont #define READ_ACCESS 0x00 #define WRITE_ACCESS 0x80 - #define SPI_SPEED 8000000 +-#define SPI_SPEED 8000000 ++#define SPI_SPEED (getenv("SPI_SPEED")==NULL ? 8000000 : getenv("SPI_SPEED")) -#define SPI_DEV_PATH "/dev/spidev0.0" +#define SPI_DEV_PATH (getenv("LORAGW_SPI")==NULL ? "/dev/spidev0.0" : getenv("LORAGW_SPI")) //#define SPI_DEV_PATH "/dev/spidev32766.0" diff --git a/deps/lgw/v5.0.1-linux.patch b/deps/lgw/v5.0.1-linux.patch index 8a2281b6..4a936202 100644 --- a/deps/lgw/v5.0.1-linux.patch +++ b/deps/lgw/v5.0.1-linux.patch @@ -125,7 +125,8 @@ index c01ed1c..0e2b64c 100644 @@ -54,7 +54,7 @@ Maintainer: Sylvain Miermont #define READ_ACCESS 0x00 #define WRITE_ACCESS 0x80 - #define SPI_SPEED 8000000 +-#define SPI_SPEED 8000000 ++#define SPI_SPEED (getenv("SPI_SPEED")==NULL ? 2000000 : getenv("SPI_SPEED")) -#define SPI_DEV_PATH "/dev/spidev0.0" +#define SPI_DEV_PATH (getenv("LORAGW_SPI")==NULL ? "/dev/spidev0.0" : getenv("LORAGW_SPI")) //#define SPI_DEV_PATH "/dev/spidev32766.0" diff --git a/deps/lgw/v5.0.1-rpi.patch b/deps/lgw/v5.0.1-rpi.patch index 8a2281b6..4a936202 100644 --- a/deps/lgw/v5.0.1-rpi.patch +++ b/deps/lgw/v5.0.1-rpi.patch @@ -125,7 +125,8 @@ index c01ed1c..0e2b64c 100644 @@ -54,7 +54,7 @@ Maintainer: Sylvain Miermont #define READ_ACCESS 0x00 #define WRITE_ACCESS 0x80 - #define SPI_SPEED 8000000 +-#define SPI_SPEED 8000000 ++#define SPI_SPEED (getenv("SPI_SPEED")==NULL ? 2000000 : getenv("SPI_SPEED")) -#define SPI_DEV_PATH "/dev/spidev0.0" +#define SPI_DEV_PATH (getenv("LORAGW_SPI")==NULL ? "/dev/spidev0.0" : getenv("LORAGW_SPI")) //#define SPI_DEV_PATH "/dev/spidev32766.0" diff --git a/deps/lgw1302/V1.0.5-corecell.patch b/deps/lgw1302/V1.0.5-corecell.patch index 27caa24c..1a9df99e 100644 --- a/deps/lgw1302/V1.0.5-corecell.patch +++ b/deps/lgw1302/V1.0.5-corecell.patch @@ -298,3 +298,393 @@ index 77c3d4d..487283f 100644 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ int timestamp_counter_mode(bool enable_precision_ts, uint8_t max_ts_metrics, uint8_t nb_symbols) { +diff --git a/libloragw/Makefile b/libloragw/Makefile +index 262167a..439b23a 100644 +--- a/libloragw/Makefile ++++ b/libloragw/Makefile +@@ -85,7 +85,7 @@ $(OBJDIR)/%.o: src/%.c $(INCLUDES) inc/config.h | $(OBJDIR) + + ### static library + +-libloragw.a: $(OBJDIR)/loragw_spi.o $(OBJDIR)/loragw_i2c.o $(OBJDIR)/loragw_aux.o $(OBJDIR)/loragw_reg.o $(OBJDIR)/loragw_sx1250.o $(OBJDIR)/loragw_sx125x.o $(OBJDIR)/loragw_sx1302.o $(OBJDIR)/loragw_cal.o $(OBJDIR)/loragw_debug.o $(OBJDIR)/loragw_hal.o $(OBJDIR)/loragw_stts751.o $(OBJDIR)/loragw_gps.o $(OBJDIR)/loragw_sx1302_timestamp.o $(OBJDIR)/loragw_sx1302_rx.o ++libloragw.a: $(OBJDIR)/loragw_spi.o $(OBJDIR)/loragw_i2c.o $(OBJDIR)/loragw_aux.o $(OBJDIR)/loragw_reg.o $(OBJDIR)/loragw_sx1250.o $(OBJDIR)/loragw_sx125x.o $(OBJDIR)/loragw_sx1302.o $(OBJDIR)/loragw_cal.o $(OBJDIR)/loragw_debug.o $(OBJDIR)/loragw_hal.o $(OBJDIR)/loragw_gps.o $(OBJDIR)/loragw_sx1302_timestamp.o $(OBJDIR)/loragw_sx1302_rx.o + $(AR) rcs $@ $^ + + ### test programs +diff --git a/libloragw/inc/loragw_stts751.h b/libloragw/inc/loragw_stts751.h +deleted file mode 100644 +index b1a898a..0000000 +--- a/libloragw/inc/loragw_stts751.h ++++ /dev/null +@@ -1,58 +0,0 @@ +-/* +- / _____) _ | | +-( (____ _____ ____ _| |_ _____ ____| |__ +- \____ \| ___ | (_ _) ___ |/ ___) _ \ +- _____) ) ____| | | || |_| ____( (___| | | | +-(______/|_____)_|_|_| \__)_____)\____)_| |_| +- (C)2019 Semtech +- +-Description: +- Basic driver for ST ts751 temperature sensor +- +-License: Revised BSD License, see LICENSE.TXT file include in the project +-*/ +- +- +-#ifndef _LORAGW_STTS751_H +-#define _LORAGW_STTS751_H +- +-/* -------------------------------------------------------------------------- */ +-/* --- DEPENDANCIES --------------------------------------------------------- */ +- +-#include /* C99 types */ +-#include /* bool type */ +- +-#include "config.h" /* library configuration options (dynamically generated) */ +- +-/* -------------------------------------------------------------------------- */ +-/* --- INTERNAL SHARED TYPES ------------------------------------------------ */ +- +-/* -------------------------------------------------------------------------- */ +-/* --- INTERNAL SHARED FUNCTIONS -------------------------------------------- */ +- +-/* -------------------------------------------------------------------------- */ +-/* --- PUBLIC CONSTANTS ----------------------------------------------------- */ +- +-#define I2C_PORT_TEMP_SENSOR_0 0x39 /* STTS751-0DP3F */ +-#define I2C_PORT_TEMP_SENSOR_1 0x3B /* STTS751-1DP3F */ +- +-/* -------------------------------------------------------------------------- */ +-/* --- PUBLIC FUNCTIONS ----------------------------------------------------- */ +- +-/** +-@brief TODO +-@param TODO +-@return TODO +-*/ +-int stts751_configure(int i2c_fd, uint8_t i2c_addr); +- +-/** +-@brief TODO +-@param TODO +-@return TODO +-*/ +-int stts751_get_temperature(int i2c_fd, uint8_t i2c_addr, float * temperature); +- +-#endif +- +-/* --- EOF ------------------------------------------------------------------ */ +diff --git a/libloragw/src/loragw_hal.c b/libloragw/src/loragw_hal.c +index 3b00c09..66d5c97 100644 +--- a/libloragw/src/loragw_hal.c ++++ b/libloragw/src/loragw_hal.c +@@ -41,7 +41,7 @@ License: Revised BSD License, see LICENSE.TXT file include in the project + #include "loragw_sx1250.h" + #include "loragw_sx125x.h" + #include "loragw_sx1302.h" +-#include "loragw_stts751.h" ++ + #include "loragw_debug.h" + + /* -------------------------------------------------------------------------- */ +@@ -181,8 +181,8 @@ static lgw_context_t lgw_context = { + FILE * log_file = NULL; + + /* I2C temperature sensor handles */ +-static int ts_fd = -1; +-static uint8_t ts_addr = 0xFF; ++//static int ts_fd = -1; ++//static uint8_t ts_addr = 0xFF; + + /* -------------------------------------------------------------------------- */ + /* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */ +@@ -719,22 +719,23 @@ int lgw_start(void) { + dbg_init_gpio(); + #endif + ++// + /* Try to configure temperature sensor STTS751-0DP3F */ +- ts_addr = I2C_PORT_TEMP_SENSOR_0; +- i2c_linuxdev_open(I2C_DEVICE, ts_addr, &ts_fd); +- err = stts751_configure(ts_fd, ts_addr); +- if (err != LGW_I2C_SUCCESS) { +- i2c_linuxdev_close(ts_fd); +- ts_fd = -1; +- /* Not found, try to configure temperature sensor STTS751-1DP3F */ +- ts_addr = I2C_PORT_TEMP_SENSOR_1; +- i2c_linuxdev_open(I2C_DEVICE, ts_addr, &ts_fd); +- err = stts751_configure(ts_fd, ts_addr); +- if (err != LGW_I2C_SUCCESS) { +- printf("ERROR: failed to configure the temperature sensor\n"); +- return LGW_HAL_ERROR; +- } +- } ++// ts_addr = I2C_PORT_TEMP_SENSOR_0; ++// i2c_linuxdev_open(I2C_DEVICE, ts_addr, &ts_fd); ++// err = stts751_configure(ts_fd, ts_addr); ++// if (err != LGW_I2C_SUCCESS) { ++// i2c_linuxdev_close(ts_fd); ++// ts_fd = -1; ++// /* Not found, try to configure temperature sensor STTS751-1DP3F */ ++// ts_addr = I2C_PORT_TEMP_SENSOR_1; ++// i2c_linuxdev_open(I2C_DEVICE, ts_addr, &ts_fd); ++// err = stts751_configure(ts_fd, ts_addr); ++// if (err != LGW_I2C_SUCCESS) { ++// printf("ERROR: failed to configure the temperature sensor\n"); ++// return LGW_HAL_ERROR; ++// } ++// } + + /* set hal state */ + CONTEXT_STARTED = true; +@@ -762,10 +763,10 @@ int lgw_stop(void) { + lgw_disconnect(); + + DEBUG_MSG("INFO: Closing I2C\n"); +- err = i2c_linuxdev_close(ts_fd); +- if (err != 0) { +- printf("ERROR: failed to close I2C device (err=%i)\n", err); +- } ++ //err = i2c_linuxdev_close(ts_fd); ++ //if (err != 0) { ++ // printf("ERROR: failed to close I2C device (err=%i)\n", err); ++ //} + + CONTEXT_STARTED = false; + return LGW_HAL_SUCCESS; +@@ -778,7 +779,9 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) { + uint8_t nb_pkt_fetched = 0; + uint16_t nb_pkt_found = 0; + uint16_t nb_pkt_left = 0; +- float current_temperature, rssi_temperature_offset; ++ //float current_temperature, rssi_temperature_offset; ++ float current_temperature = 30.0; ++ float rssi_temperature_offset; + + /* Check that AGC/ARB firmwares are not corrupted, and update internal counter */ + /* WARNING: this needs to be called regularly by the upper layer */ +@@ -802,11 +805,11 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) { + } + + /* Apply RSSI temperature compensation */ +- res = stts751_get_temperature(ts_fd, ts_addr, ¤t_temperature); +- if (res != LGW_I2C_SUCCESS) { +- printf("ERROR: failed to get current temperature\n"); +- return LGW_HAL_ERROR; +- } ++ //res = stts751_get_temperature(ts_fd, ts_addr, ¤t_temperature); ++ //if (res != LGW_I2C_SUCCESS) { ++ // printf("ERROR: failed to get current temperature\n"); ++ // return LGW_HAL_ERROR; ++ //} + + /* Iterate on the RX buffer to get parsed packets */ + for (nb_pkt_found = 0; nb_pkt_found < ((nb_pkt_fetched <= max_pkt) ? nb_pkt_fetched : max_pkt); nb_pkt_found++) { +@@ -982,10 +985,10 @@ int lgw_get_eui(uint64_t* eui) { + + int lgw_get_temperature(float* temperature) { + CHECK_NULL(temperature); +- +- if (stts751_get_temperature(ts_fd, ts_addr, temperature) != LGW_I2C_SUCCESS) { +- return LGW_HAL_ERROR; +- } ++ *temperature = 30.0; ++ //if (stts751_get_temperature(ts_fd, ts_addr, temperature) != LGW_I2C_SUCCESS) { ++ // return LGW_HAL_ERROR; ++ //} + + return LGW_HAL_SUCCESS; + } +diff --git a/libloragw/src/loragw_stts751.c b/libloragw/src/loragw_stts751.c +deleted file mode 100644 +index c417dc2..0000000 +--- a/libloragw/src/loragw_stts751.c ++++ /dev/null +@@ -1,186 +0,0 @@ +-/* +- / _____) _ | | +-( (____ _____ ____ _| |_ _____ ____| |__ +- \____ \| ___ | (_ _) ___ |/ ___) _ \ +- _____) ) ____| | | || |_| ____( (___| | | | +-(______/|_____)_|_|_| \__)_____)\____)_| |_| +- (C)2019 Semtech +- +-Description: +- Basic driver for ST ts751 temperature sensor +- +-License: Revised BSD License, see LICENSE.TXT file include in the project +-*/ +- +- +-/* -------------------------------------------------------------------------- */ +-/* --- DEPENDANCIES --------------------------------------------------------- */ +- +-#include /* C99 types */ +-#include /* bool type */ +-#include /* printf fprintf */ +- +-#include "loragw_i2c.h" +-#include "loragw_stts751.h" +- +-/* -------------------------------------------------------------------------- */ +-/* --- PRIVATE MACROS ------------------------------------------------------- */ +- +-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +-#if DEBUG_I2C == 1 +- #define DEBUG_MSG(str) fprintf(stderr, str) +- #define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args) +- #define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_REG_ERROR;} +-#else +- #define DEBUG_MSG(str) +- #define DEBUG_PRINTF(fmt, args...) +- #define CHECK_NULL(a) if(a==NULL){return LGW_REG_ERROR;} +-#endif +- +-/* -------------------------------------------------------------------------- */ +-/* --- PRIVATE CONSTANTS ---------------------------------------------------- */ +- +-#define STTS751_REG_TEMP_H 0x00 +-#define STTS751_REG_STATUS 0x01 +-#define STTS751_STATUS_TRIPT BIT(0) +-#define STTS751_STATUS_TRIPL BIT(5) +-#define STTS751_STATUS_TRIPH BIT(6) +-#define STTS751_REG_TEMP_L 0x02 +-#define STTS751_REG_CONF 0x03 +-#define STTS751_CONF_RES_MASK 0x0C +-#define STTS751_CONF_RES_SHIFT 2 +-#define STTS751_CONF_EVENT_DIS BIT(7) +-#define STTS751_CONF_STOP BIT(6) +-#define STTS751_REG_RATE 0x04 +-#define STTS751_REG_HLIM_H 0x05 +-#define STTS751_REG_HLIM_L 0x06 +-#define STTS751_REG_LLIM_H 0x07 +-#define STTS751_REG_LLIM_L 0x08 +-#define STTS751_REG_TLIM 0x20 +-#define STTS751_REG_HYST 0x21 +-#define STTS751_REG_SMBUS_TO 0x22 +- +-#define STTS751_REG_PROD_ID 0xFD +-#define STTS751_REG_MAN_ID 0xFE +-#define STTS751_REG_REV_ID 0xFF +- +-#define STTS751_0_PROD_ID 0x00 +-#define STTS751_1_PROD_ID 0x01 +-#define ST_MAN_ID 0x53 +- +-/* -------------------------------------------------------------------------- */ +-/* --- PRIVATE VARIABLES ---------------------------------------------------- */ +- +-/* -------------------------------------------------------------------------- */ +-/* --- INTERNAL SHARED VARIABLES -------------------------------------------- */ +- +-/* -------------------------------------------------------------------------- */ +-/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */ +- +-/* -------------------------------------------------------------------------- */ +-/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */ +- +-int stts751_configure(int i2c_fd, uint8_t i2c_addr) { +- int err; +- uint8_t val; +- +- /* Check Input Params */ +- if (i2c_fd <= 0) { +- printf("ERROR: invalid I2C file descriptor\n"); +- return LGW_I2C_ERROR; +- } +- +- DEBUG_PRINTF("INFO: configuring STTS751 temperature sensor on 0x%02X...\n", i2c_addr); +- +- /* Get product ID and test which sensor is mounted */ +- err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_PROD_ID, &val); +- if (err != 0) { +- DEBUG_PRINTF("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err); +- return LGW_I2C_ERROR; +- } +- switch (val) { +- case STTS751_0_PROD_ID: +- DEBUG_MSG("INFO: Product ID: STTS751-0\n"); +- break; +- case STTS751_1_PROD_ID: +- DEBUG_MSG("INFO: Product ID: STTS751-1\n"); +- break; +- default: +- printf("ERROR: Product ID: UNKNOWN\n"); +- return LGW_I2C_ERROR; +- } +- +- /* Get Manufacturer ID */ +- err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_MAN_ID, &val); +- if (err != 0) { +- DEBUG_PRINTF("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err); +- return LGW_I2C_ERROR; +- } +- if (val != ST_MAN_ID) { +- printf("ERROR: Manufacturer ID: UNKNOWN\n"); +- return LGW_I2C_ERROR; +- } else { +- DEBUG_PRINTF("INFO: Manufacturer ID: 0x%02X\n", val); +- } +- +- /* Get revision number */ +- err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_REV_ID, &val); +- if (err != 0) { +- DEBUG_PRINTF("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err); +- return LGW_I2C_ERROR; +- } +- DEBUG_PRINTF("INFO: Revision number: 0x%02X\n", val); +- +- /* Set conversion resolution to 12 bits */ +- err = i2c_linuxdev_write(i2c_fd, i2c_addr, STTS751_REG_CONF, 0x8C); /* TODO: do not hardcode the whole byte */ +- if (err != 0) { +- DEBUG_PRINTF("ERROR: failed to write I2C device 0x%02X (err=%i)\n", i2c_addr, err); +- return LGW_I2C_ERROR; +- } +- +- /* Set conversion rate to 1 / second */ +- err = i2c_linuxdev_write(i2c_fd, i2c_addr, STTS751_REG_RATE, 0x04); +- if (err != 0) { +- DEBUG_PRINTF("ERROR: failed to write I2C device 0x%02X (err=%i)\n", i2c_addr, err); +- return LGW_I2C_ERROR; +- } +- +- return LGW_I2C_SUCCESS; +-} +- +-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +- +-int stts751_get_temperature(int i2c_fd, uint8_t i2c_addr, float * temperature) { +- int err; +- uint8_t high_byte, low_byte; +- int8_t h; +- +- /* Check Input Params */ +- if (i2c_fd <= 0) { +- printf("ERROR: invalid I2C file descriptor\n"); +- return LGW_I2C_ERROR; +- } +- +- /* Read Temperature LSB */ +- err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_TEMP_L, &low_byte); +- if (err != 0) { +- printf("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err); +- return LGW_I2C_ERROR; +- } +- +- /* Read Temperature MSB */ +- err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_TEMP_H, &high_byte); +- if (err != 0) { +- printf("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err); +- return LGW_I2C_ERROR; +- } +- +- h = (int8_t)high_byte; +- *temperature = ((h << 8) | low_byte) / 256.0; +- +- DEBUG_PRINTF("Temperature: %f C (h:0x%02X l:0x%02X)\n", *temperature, high_byte, low_byte); +- +- return LGW_I2C_SUCCESS; +-} +- +-/* --- EOF ------------------------------------------------------------------ */ diff --git a/deps/mbedtls/prep.sh b/deps/mbedtls/prep.sh index 2875cd72..4f774f04 100755 --- a/deps/mbedtls/prep.sh +++ b/deps/mbedtls/prep.sh @@ -30,7 +30,7 @@ set -e cd $(dirname $0) if [[ ! -d git-repo ]]; then - git clone -b mbedtls-2.6 --single-branch --depth 1 https://github.com/ARMmbed/mbedtls.git git-repo + git clone -b mbedtls-2.7.5 --single-branch --depth 1 https://github.com/ARMmbed/mbedtls.git git-repo fi if [[ -z "$platform" ]] || [[ -z "$variant" ]]; then diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..75723368 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +version: 2 + +services: + + basicstation: + build: . + container_name: basicstation + restart: unless-stopped + privileged: true + network_mode: host # required to read main interface MAC instead of virtual one + environment: + MODEL: "SX1301" + GW_GPS: "false" + GW_RESET_GPIO: 17 + GW_ENABLE_GPIO: 0 + TTN_STACK_VERSION: 3 + TTN_REGION: "eu1" + #TC_URI: # uses TTN server by default, based on the TTN_STACK_VERSION and TTN_REGION variables + #TC_TRUST: # uses TTN certificates by default + TC_KEY: + #EUI_ADDRESS: # required if you use a Pi Zero W or Pi Zero 2 W + labels: + io.balena.features.balena-api: '1' diff --git a/examples/corecell/lns-ttn/station.conf b/examples/corecell/lns-ttn/station.conf index 4618940f..ceaf9b26 100644 --- a/examples/corecell/lns-ttn/station.conf +++ b/examples/corecell/lns-ttn/station.conf @@ -49,5 +49,4 @@ "log_size": 10000000, "log_rotate": 3 } -} - +} \ No newline at end of file diff --git a/examples/corecell/reset_lgw.sh b/examples/corecell/reset_lgw.sh index 0136d72e..f3c44dc5 100755 --- a/examples/corecell/reset_lgw.sh +++ b/examples/corecell/reset_lgw.sh @@ -11,8 +11,8 @@ # GPIO mapping has to be adapted with HW # -SX1302_RESET_PIN=23 -SX1302_POWER_EN_PIN=18 +SX1302_RESET_PIN=${GW_RESET_GPIO:-17} +SX1302_POWER_EN_PIN=${GW_POWER_EN_GPIO:-18} WAIT_GPIO() { sleep 0.1 @@ -29,8 +29,8 @@ init() { } reset() { - echo "CoreCell reset through GPIO$SX1302_RESET_PIN..." - echo "CoreCell power enable through GPIO$SX1302_POWER_EN_PIN..." + echo "RAK2287 reset through GPIO$SX1302_RESET_PIN..." + echo "RAK2287 power enable through GPIO$SX1302_POWER_EN_PIN..." # write output for SX1302 CoreCell power_enable and reset echo "1" > /sys/class/gpio/gpio$SX1302_POWER_EN_PIN/value; WAIT_GPIO @@ -67,4 +67,4 @@ case "$1" in ;; esac -exit 0 \ No newline at end of file +exit 0 diff --git a/examples/corecell/start-station.sh b/examples/corecell/start-station.sh index 5317c199..0ef69ccf 100755 --- a/examples/corecell/start-station.sh +++ b/examples/corecell/start-station.sh @@ -78,11 +78,10 @@ fi STATION_BIN="../../build-corecell-$variant/bin/station" - if [ -f "$STATION_BIN" ]; then printf "Using variant=$variant, lns_config='$lns_config'\n" printf "$GREEN Starting Station ... $NC\n" - $STATION_BIN -h $lns_config + $STATION_BIN -f -h $lns_config else printf "$RED [ERROR]: Binary not found @ $STATION_BIN $NC\n" fi diff --git a/examples/live-s2.sm.tc/cups-boot.crt b/examples/live-s2.sm.tc/cups-boot.crt deleted file mode 100644 index 76b5420f..00000000 --- a/examples/live-s2.sm.tc/cups-boot.crt +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBkzCCATmgAwIBAgIBQTAKBggqhkjOPQQDAjBXMRAwDgYDVQQDDAdSb290IENB -MSAwHgYDVQQLDBdUcmFja0NlbnRyYWwgKGVpYVBvVWM5KTEUMBIGA1UECgwLVHJh -Y2tOZXQuaW8xCzAJBgNVBAYTAkNIMB4XDTE5MDMwNzE1MjgwNVoXDTIxMDMwNjE1 -MjgwNVowTzETMBEGA1UEAwwKZ3dwcm92LTo6MDEVMBMGA1UECwwMVHJhY2tDZW50 -cmFsMRQwEgYDVQQKDAtUcmFja05ldC5pbzELMAkGA1UEBhMCQ0gwWTATBgcqhkjO -PQIBBggqhkjOPQMBBwNCAASFyfmqBPkza9kd2IkrbU3zSRIriq5vOcgwfilctZVs -j8Z7XVBMdNLjriSjchVgyBTJfvMVMbvYTdzD7w5GBSNwMAoGCCqGSM49BAMCA0gA -MEUCIQCFGgSlP6GYM6uXd6KXuEwc098p5orHP/dxupGAZifquwIgbUh9UAR8tgAi -8TH36s9z+mz27ea7ezcmH8aM4W3Meng= ------END CERTIFICATE----- diff --git a/examples/live-s2.sm.tc/cups-boot.key b/examples/live-s2.sm.tc/cups-boot.key deleted file mode 100644 index 6c00c4e6..00000000 --- a/examples/live-s2.sm.tc/cups-boot.key +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN EC PRIVATE KEY----- -MHcCAQEEIJbt0pUj24UIWS6HngUqJtP3uPpweSIqhB4TRoyHdzdqoAoGCCqGSM49 -AwEHoUQDQgAEhcn5qgT5M2vZHdiJK21N80kSK4qubznIMH4pXLWVbI/Ge11QTHTS -464ko3IVYMgUyX7zFTG72E3cw+8ORgUjcA== ------END EC PRIVATE KEY----- diff --git a/examples/live-s2.sm.tc/cups-boot.trust b/examples/live-s2.sm.tc/cups-boot.trust deleted file mode 100644 index 03178ecf..00000000 --- a/examples/live-s2.sm.tc/cups-boot.trust +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBlzCCATwCAQwwCgYIKoZIzj0EAwIwVzEQMA4GA1UEAwwHUm9vdCBDQTEgMB4G -A1UECwwXVHJhY2tDZW50cmFsIChlaWFQb1VjOSkxFDASBgNVBAoMC1RyYWNrTmV0 -LmlvMQswCQYDVQQGEwJDSDAeFw0xODExMDgxMjQyMDBaFw0yNDExMDYxMjQyMDBa -MFcxEDAOBgNVBAMMB1Jvb3QgQ0ExIDAeBgNVBAsMF1RyYWNrQ2VudHJhbCAoZWlh -UG9VYzkpMRQwEgYDVQQKDAtUcmFja05ldC5pbzELMAkGA1UEBhMCQ0gwWTATBgcq -hkjOPQIBBggqhkjOPQMBBwNCAAQpHfNq86xR2+pZY0dpurnn7IrkH9YaBoEGQ3K+ -ZXDYaR2PviPw8sbClqQG/pYEYsLpWNk9UeJtFv5oJtFXmgC9MAoGCCqGSM49BAMC -A0kAMEYCIQDQBlCSN+Bo+U2xnaPBE9RWUVjY9/95I64rilCRofn0kwIhAJZ3zlGc -yO4Wie3jJKKNCxOioaJZUdaJZUo14vkH9OFp ------END CERTIFICATE----- diff --git a/examples/live-s2.sm.tc/cups-boot.uri b/examples/live-s2.sm.tc/cups-boot.uri deleted file mode 100644 index bfa9fa97..00000000 --- a/examples/live-s2.sm.tc/cups-boot.uri +++ /dev/null @@ -1 +0,0 @@ -https://s2.sm.tc:7007 \ No newline at end of file diff --git a/examples/live-s2.sm.tc/makefile b/examples/live-s2.sm.tc/makefile index 80fce24f..c7634af7 100644 --- a/examples/live-s2.sm.tc/makefile +++ b/examples/live-s2.sm.tc/makefile @@ -39,6 +39,6 @@ kerlink: platform=kerlink variant=std make clean: - rm -rf cups.* cups-bak.* tc.* tc-bak.* station.log station.pid + rm -rf cups.* cups-bak.* tc-bak.* station.log station.pid .PHONY: all clean diff --git a/examples/live-s2.sm.tc/tc.trust b/examples/live-s2.sm.tc/tc.trust new file mode 100644 index 00000000..b2e43c93 --- /dev/null +++ b/examples/live-s2.sm.tc/tc.trust @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- diff --git a/examples/live-s2.sm.tc/tc.uri b/examples/live-s2.sm.tc/tc.uri new file mode 100644 index 00000000..351c5c87 --- /dev/null +++ b/examples/live-s2.sm.tc/tc.uri @@ -0,0 +1,2 @@ +wss://lns.eu.thethings.network:443 + diff --git a/logo.png b/logo.png new file mode 100644 index 00000000..9e310d01 Binary files /dev/null and b/logo.png differ diff --git a/setup.gmk b/setup.gmk index a123556f..a25e74df 100644 --- a/setup.gmk +++ b/setup.gmk @@ -35,18 +35,25 @@ NQ = $(if ${V},>/dev/null,) platform ?= linux variant ?= std +arch ?= default -include ${TD}/setup-${platform}.gmk LOCAL_ARCH := $(shell gcc -dumpmachine) -ARCH.linux = x86_64-linux-gnu -ARCH.linuxV2 = x86_64-linux-gnu -ARCH.linuxpico = x86_64-linux-gnu -ARCH.corecell = arm-linux-gnueabihf -ARCH.rpi = arm-linux-gnueabihf -ARCH.kerlink = arm-klk-linux-gnueabi -ARCH=${ARCH.${platform}} +ARCH.linux.default = x86_64-linux-gnu +ARCH.linuxV2.default = x86_64-linux-gnu +ARCH.linuxpico.default = x86_64-linux-gnu +ARCH.corecell.default = arm-linux-gnueabihf +ARCH.corecell.rpi = arm-linux-gnueabihf +ARCH.corecell.armv7hf = arm-linux-gnueabihf +ARCH.corecell.aarch64 = aarch64-linux-gnu +ARCH.rpi.default = arm-linux-gnueabihf +ARCH.rpi.rpi = arm-linux-gnueabihf +ARCH.rpi.armv7hf = arm-linux-gnueabihf +ARCH.rpi.aarch64 = aarch64-linux-gnu +ARCH.kerlink.default = arm-klk-linux-gnueabi +ARCH=${ARCH.${platform}.${arch}} export TDfull := $(shell cd ${TD} && pwd) TOOLCHAIN=${HOME}/toolchain-${platform} diff --git a/src-linux/sys_linux.c b/src-linux/sys_linux.c index 5b637c9e..019095f4 100644 --- a/src-linux/sys_linux.c +++ b/src-linux/sys_linux.c @@ -204,9 +204,12 @@ static void findDefaultEui () { if( ifc[0] != 0 ) { if( strncmp(ifc, "eth", 3) == 0 && strncmp(dname, "eth", 3) != 0 ) continue; // eth trumps other devices + // in case there is no eth0 + if( strncmp(ifc, "wla", 3) == 0 && strncmp(dname, "wla", 3) != 0 ) + continue; // wlan trumps other devices // Otherwie choose alphabetically lowest - unless eth replaces something else if( !((strncmp(ifc, "eth", 3) == 0) ^ (strncmp(dname, "eth", 3) == 0)) - && strcmp(ifc, dname) <= 0 ) + && strcmp(ifc, dname) > 0 ) continue; // not lower } strcpy(ifc, dname); @@ -219,6 +222,7 @@ static void findDefaultEui () { protoEUI = eui; rt_free((void*)protoEuiSrc); protoEuiSrc = rt_strdup(path); + LOG(MOD_SYS|INFO, "findDefaultEui -> protoEuiSrc %s - protoEUI %lu", protoEuiSrc, protoEUI); } } @@ -366,7 +370,7 @@ void sys_ini () { logfile.path==NULL ? "stderr" : logfile.path, logfile.size, logfile.rotate); LOG(MOD_SYS|INFO, "Station Ver : %s", CFG_version " " CFG_bdate); LOG(MOD_SYS|INFO, "Package Ver : %s", sys_version()); - LOG(MOD_SYS|INFO, "proto EUI : %:E\t(%s)", protoEUI, protoEuiSrc); + LOG(MOD_SYS|INFO, "proto EUI(x) : %:E\t(%s)", protoEUI, protoEuiSrc); LOG(MOD_SYS|INFO, "prefix EUI : %:E\t(%s)", prefixEUI, prefixEuiSrc); LOG(MOD_SYS|INFO, "Station EUI : %:E", sys_eui()); LOG(MOD_SYS|INFO, "Station home: %s\t(%s)", homeDir, homeDirSrc); diff --git a/start.sh b/start.sh new file mode 100644 index 00000000..dd5c8328 --- /dev/null +++ b/start.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +TAG_KEY="EUI" + +if [ -z ${EUI_ADDRESS} ] ; + then + TTN_EUI=$(cat /sys/class/net/eth0/address | sed -r 's/[:]+//g' | sed -e 's#\(.\{6\}\)\(.*\)#\1fffe\2#g') + else + echo "Using DEVICE: $EUI_ADDRESS" + TTN_EUI=$(cat /sys/class/net/wlan0/address | sed -r 's/[:]+//g' | sed -e 's#\(.\{6\}\)\(.*\)#\1fffe\2#g') +fi + + +echo "Gateway EUI: $TTN_EUI" + +ID=$(curl -sX GET "https://api.balena-cloud.com/v5/device?\$filter=uuid%20eq%20'$BALENA_DEVICE_UUID'" \ +-H "Content-Type: application/json" \ +-H "Authorization: Bearer $BALENA_API_KEY" | \ +jq ".d | .[0] | .id") + +TAG=$(curl -sX POST \ +"https://api.balena-cloud.com/v5/device_tag" \ +-H "Content-Type: application/json" \ +-H "Authorization: Bearer $BALENA_API_KEY" \ +--data "{ \"device\": \"$ID\", \"tag_key\": \"$TAG_KEY\", \"value\": \"$TTN_EUI\" }" > /dev/null) + + + +if [ -z ${MODEL} ] ; + then + echo -e "\033[91mWARNING: MODEL variable not set.\n Set the model of the gateway you are using (SX1301 or SX1302).\033[0m" + balena-idle + else + echo "Using MODEL: $MODEL" + if [ "$MODEL" = "SX1301" ] || [ "$MODEL" = "RAK2245" ] || [ "$MODEL" = "iC880a" ];then + ./start_sx1301.sh + fi + if [ "$MODEL" = "SX1302" ] || [ "$MODEL" = "RAK2287" ];then + ./start_sx1302.sh + fi +fi + +#balena-idle diff --git a/start_common.sh b/start_common.sh new file mode 100644 index 00000000..d564ba14 --- /dev/null +++ b/start_common.sh @@ -0,0 +1,34 @@ +# Defaults to TTN server v2, EU region +TTN_STACK_VERSION=${TTN_STACK_VERSION:-3} +if [ $TTN_STACK_VERSION -eq 2 ]; then + TTN_REGION=${TTN_REGION:-"eu"} + TC_URI=${TC_URI:-"wss://lns.${TTN_REGION}.thethings.network:443"} +elif [ $TTN_STACK_VERSION -eq 3 ]; then + TTN_REGION=${TTN_REGION:-"eu1"} + TC_URI=${TC_URI:-"wss://${TTN_REGION}.cloud.thethings.network:8887"} +else + echo -e "\033[91mERROR: Wrong TTN_STACK_VERSION value, should be either 2 o 3.\033[0m" + balena-idle +fi + +# Get certificate +TC_TRUST=${TC_TRUST:-$(curl --silent "https://letsencrypt.org/certs/{trustid-x3-root.pem.txt,isrgrootx1.pem}")} + +# Sanitize TC_TRUST +TC_TRUST=$(echo $TC_TRUST | sed 's/\s//g' | sed 's/-----BEGINCERTIFICATE-----/-----BEGIN CERTIFICATE-----\n/g' | sed 's/-----ENDCERTIFICATE-----/\n-----END CERTIFICATE-----\n/g' | sed 's/\n+/\n/g') + +# Check configuration +if [ "$TC_URI" == "" ] || [ "$TC_TRUST" == "" ] +then + echo -e "\033[91mERROR: Missing configuration, define either TTN_STACK_VERSION or TC_URI and TC_TRUST.\033[0m" + balena-idle +fi + +echo "Server: $TC_URI" + +# declare map of hardware pins to GPIO on Raspberry Pi +declare -a pinToGPIO +pinToGPIO=( -1 -1 -1 2 -1 3 -1 4 14 -1 15 17 18 27 -1 22 23 -1 24 10 -1 9 25 11 8 -1 7 0 1 5 -1 6 12 13 -1 19 16 26 20 -1 21) +GW_RESET_PIN=${GW_RESET_PIN:-11} +GW_RESET_GPIO=${GW_RESET_GPIO:-${pinToGPIO[$GW_RESET_PIN]}} +LORAGW_SPI=${LORAGW_SPI:-"/dev/spidev0.0"} diff --git a/start_sx1301.sh b/start_sx1301.sh new file mode 100755 index 00000000..b170f919 --- /dev/null +++ b/start_sx1301.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# Load common variables +source ./start_common.sh + +# Change to project folder +cd examples/live-s2.sm.tc + +# Setup TC files from environment +echo "$TC_URI" > tc.uri +echo "$TC_TRUST" > tc.trust +if [ ! -z ${TC_KEY} ]; then + echo "Authorization: Bearer $TC_KEY" | perl -p -e 's/\r\n|\n|\r/\r\n/g' > tc.key +fi + +# Reset gateway +echo "Resetting gateway concentrator on GPIO $GW_RESET_GPIO" +echo $GW_RESET_GPIO > /sys/class/gpio/export +echo out > /sys/class/gpio/gpio$GW_RESET_GPIO/direction +echo 0 > /sys/class/gpio/gpio$GW_RESET_GPIO/value +sleep 1 +echo 1 > /sys/class/gpio/gpio$GW_RESET_GPIO/value +sleep 1 +echo 0 > /sys/class/gpio/gpio$GW_RESET_GPIO/value +sleep 1 +echo $GW_RESET_GPIO > /sys/class/gpio/unexport + +RADIODEV=$LORAGW_SPI ../../build-rpi-std/bin/station diff --git a/start_sx1302.sh b/start_sx1302.sh new file mode 100755 index 00000000..c244d172 --- /dev/null +++ b/start_sx1302.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +# Load common variables +source ./start_common.sh + +# Change to project folder +cd examples/corecell + +# Setup TC files from environment +echo "$TC_URI" > ./lns-ttn/tc.uri +echo "$TC_TRUST" > ./lns-ttn/tc.trust +if [ ! -z ${TC_KEY} ]; then + echo "Authorization: Bearer $TC_KEY" | perl -p -e 's/\r\n|\n|\r/\r\n/g' > ./lns-ttn/tc.key +fi + +# Set other environment variables +export GW_RESET_GPIO=$GW_RESET_GPIO +export GW_POWER_EN_GPIO=$GW_POWER_EN_GPIO + +./start-station.sh -l ./lns-ttn