Skip to content
This repository has been archived by the owner on Sep 3, 2020. It is now read-only.

Commit

Permalink
Merge pull request #29 from TheThingsNetwork/develop
Browse files Browse the repository at this point in the history
Packet forwarder v2.0.1
  • Loading branch information
Eric Gourlaouen authored May 15, 2017
2 parents df860e3 + 3663f38 commit 2ac53a3
Show file tree
Hide file tree
Showing 21 changed files with 469 additions and 107 deletions.
41 changes: 32 additions & 9 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ before_script:
- mkdir -p $GOPATH/.cache && ln -s $PWD/.govendor $GOPATH/.cache/govendor
# Downloading go if not installed yet
- apt-get update -y && apt-get install make git tar -y
- "([[ ! $(go version) =~ \"go1\\.8\" ]] && apt-get install wget -y && wget https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz && tar -C $PWD -xvzf go1.8.1.linux-amd64.tar.gz) || echo \"Expected Go toolset available in cache\""
- "([[ ! $(go version) =~ \"version\" ]] && apt-get install wget -y && wget https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz && tar -C $PWD -xvzf go1.8.1.linux-amd64.tar.gz) || echo \"Expected Go toolset available in cache\""
# Copying the packet-forwarder in the gopath
- mkdir -p $GOPATH/src/github.com/TheThingsNetwork
- ln -s $PWD $GOPATH/src/github.com/TheThingsNetwork/packet_forwarder
Expand All @@ -36,9 +36,20 @@ before_script:
- make deps
- popd

after_script:
- cp -r release release_files
- pushd release_files
# Change name of the binary
- mv packet-forwarder* packet-forwarder
# Create archive
- tar -cvzf $CI_JOB_NAME.tar.gz *
- popd
- rm -rf release/*
- cp release_files/$CI_JOB_NAME.tar.gz release

multitech-conduit-pktfwd:
stage: build
image: registry.gitlab.com/thethingsindustries/packet-forwarder/multitech-toolchain
image: registry.gitlab.com/thethingsnetwork/packet_forwarder/multitech-toolchain
script:
# Remove the toolchain's CFLAGS
- "sed 's/.*CFLAGS.*//g' /opt/mlinux/3.2.0/environment-setup-arm926ejste-mlinux-linux-gnueabi -i.bak"
Expand All @@ -48,29 +59,40 @@ multitech-conduit-pktfwd:
# Go to packet forwarder file
- pushd $GOPATH/src/github.com/TheThingsNetwork/packet_forwarder
- GOOS=linux GOARM=5 GOARCH=arm make build
- pushd release
- binary_file=$(ls packet*)
- ./../scripts/multitech/create-multitech-package.sh $binary_file
- popd
- cp scripts/multitech/* release
- popd
artifacts:
paths:
- release/

kerlink-iot-station-pktfwd:
stage: build
image: registry.gitlab.com/thethingsindustries/packet-forwarder/klk-toolchain
image: registry.gitlab.com/thethingsnetwork/packet_forwarder/klk-toolchain
script:
- pushd $GOPATH/src/github.com/TheThingsNetwork/packet_forwarder
- ./scripts/kerlink/build-kerlink.sh /opt
- cp scripts/kerlink/create-kerlink-package.sh release
- cp scripts/kerlink/create-package.sh release
- popd
artifacts:
paths:
- release/

imst-rpi-pktfwd:
stage: build
image: "ubuntu:xenial"
script:
- pushd $GOPATH/src/github.com/TheThingsNetwork/packet_forwarder
- apt install -y gcc-arm-linux-gnueabi # Installing cross-compiler
- GOOS=linux GOARM=7 GOARCH=arm PLATFORM=imst_rpi CFG_SPI=native CC=arm-linux-gnueabi-gcc make build
- cp scripts/rpi/install-systemd.sh release
- popd
artifacts:
paths:
- release/

sign:
before_script: []
after_script: []
only:
- develop@thethingsnetwork/packet_forwarder
- master@thethingsnetwork/packet_forwarder
Expand All @@ -89,12 +111,13 @@ sign:

azure-binaries:
before_script: []
after_script: []
only:
- develop@thethingsnetwork/packet_forwarder
- master@thethingsnetwork/packet_forwarder
stage: package
image: registry.gitlab.com/thethingsindustries/upload
script:
- cd release
- export STORAGE_CONTAINER=packet-forwarder STORAGE_KEY=$AZURE_STORAGE_KEY ZIP=true TGZ=true PREFIX=$CI_BUILD_REF_NAME/
- export STORAGE_CONTAINER=packet-forwarder STORAGE_KEY=$AZURE_STORAGE_KEY ZIP=false TGZ=false PREFIX=$CI_BUILD_REF_NAME/
- upload *
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ Installation manuals are available for main available gateways:

+ [Kerlink IoT Station installation manual](docs/INSTALL_INSTRUCTIONS/KERLINK.md)
+ [Multitech Conduit installation manual](docs/INSTALL_INSTRUCTIONS/MULTITECH.md)
+ [Raspberry Pi + IMST ic880a installation manual](docs/INSTALL_INSTRUCTIONS/IMST_RPI.md)

## <a name="build"></a>Build

If you have a custom-made gateway, or if you want to contribute to the development of the packet forwarder, you will have to build the binary yourself.

+ [Kerlink IoT Station build instructions](docs/INSTALL_INSTRUCTIONS/KERLINK.md#build)
+ [Multitech Conduit build instructions](docs/INSTALL_INSTRUCTIONS/MULTITECH.md#build)
+ [Raspberry Pi + IMST ic880a build instructions](docs/INSTALL_INSTRUCTIONS/IMST_RPI.md#build)
+ [SPI environment build instructions](docs/INSTALL_INSTRUCTIONS/SPI.md)
+ [FTDI environment build instructions](docs/INSTALL_INSTRUCTIONS/FTDI.md) *(Experimental)*

Expand Down
9 changes: 2 additions & 7 deletions cmd/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
package cmd

import (
"fmt"
"os"

"github.com/TheThingsNetwork/packet_forwarder/util"
Expand All @@ -21,10 +20,6 @@ The first argument is used as the storage location to the configuration file. If

Run: func(cmd *cobra.Command, args []string) {
ctx := util.GetLogger()
filePath := fmt.Sprintf("%s/.pktfwd.yml", os.Getenv("HOME"))
if len(args) > 0 {
filePath = args[0]
}

ctx.Info("If you haven't registered your gateway yet, you can register it either with the console, or with `ttnctl`.")

Expand Down Expand Up @@ -62,14 +57,14 @@ The first argument is used as the storage location to the configuration file. If
util.GetLogger().WithError(err).Fatal("Failed to generate YAML")
}

f, err := os.Create(filePath)
f, err := os.Create(cfgFile)
if err != nil {
util.GetLogger().WithError(err).Fatal("Failed to create file")
}
defer f.Close()

f.Write(output)
ctx.WithField("ConfigFilePath", filePath).Info("New configuration file saved")
ctx.WithField("ConfigFilePath", cfgFile).Info("New configuration file saved")
},
}

Expand Down
14 changes: 10 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"strings"

"github.com/TheThingsNetwork/packet_forwarder/util"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
Expand Down Expand Up @@ -35,6 +36,10 @@ func init() {
}

func initConfig() {
if cfgFile == "" {
cfgFile = util.GetConfigFile()
}

viper.SetConfigType("yaml")
viper.SetConfigName(".pktfwd")
viper.AddConfigPath("$HOME")
Expand All @@ -46,9 +51,10 @@ func initConfig() {
viper.SetConfigFile(cfgFile)
}

err := viper.ReadInConfig()
if err != nil {
fmt.Println("Error when reading config file:", err)
os.Exit(1)
if _, err := os.Stat(cfgFile); err == nil {
err := viper.ReadInConfig()
if err != nil {
fmt.Println("Error when reading config file:", err, "; If the file doesn't exist yet, create .pktfwd.yml by using the `configure` command.")
}
}
}
10 changes: 9 additions & 1 deletion cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
)

// standardDownlinkSendMargin is the time we send a TX packet to the concentrator before its sending time.
const standardDownlinkSendMargin = 20
const standardDownlinkSendMargin = 100

// downlinksMargin is specified at build. If it contains a numeric value, it is used as the number of
// milliseconds of time margin. If no numeric value can be parsed, we use standardTimeMargin.
Expand Down Expand Up @@ -52,6 +52,13 @@ var startCmd = &cobra.Command{
ctx.WithField("File", traceFilename).Info("Trace writing active for this run")
}

if pin := config.GetInt("reset-pin"); pin != 0 {
ctx.WithField("ResetPin", pin).Info("Reset pin specified, resetting concentrator...")
if err := pktfwd.ResetPin(pin); err != nil {
ctx.WithError(err).Fatal("Couldn't reset pin")
}
}

ttnConfig := &pktfwd.TTNConfig{
ID: config.GetString("id"),
Key: config.GetString("key"),
Expand Down Expand Up @@ -83,6 +90,7 @@ func init() {
startCmd.PersistentFlags().String("gps-path", "", "The file system path to the GPS interface, if a GPS is available (example: /dev/nmea)")
startCmd.PersistentFlags().Int64("downlink-send-margin", getDefaultDownlinkSendMargin(), "The margin, in milliseconds, between a downlink is sent to a concentrator and it is being sent by the concentrator")
startCmd.PersistentFlags().String("run-trace", "", "File to which write the runtime trace of the packet forwarder. Can later be read with `go tool trace <trace_file>`.")
startCmd.PersistentFlags().Int("reset-pin", 0, "GPIO pin associated to the reset pin of the board")
startCmd.PersistentFlags().BoolP("verbose", "v", false, "Show debug logs")

viper.BindPFlags(startCmd.PersistentFlags())
Expand Down
6 changes: 3 additions & 3 deletions docs/IMPLEMENTATION/DOWNLINKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ The method we use to find `ConcentratorBootTime` is through the first uplink. Wi

It is important to note that because of the uplink polling rate, `count_us` only allows us to find `ConcentratorBootTime` within 100μs. When the packet forwarder starts, it polls for uplinks every 100μs, to have a higher degree of precision for the `ConcentratorBootTime` value calculation. When the first uplink has been received, the polling frequency is diminished to every 5ms, to avoid performance issues.

* When a downlink is received, the packet forwarder schedules it in an internal queue system to be handled **20ms before `ExpectedSendingTimestamp`**. This means that the packet forwarder has then 20ms to perform its last computations on the downlink packet and to transmit it. This 20ms margin value is called `sendingTimeMargin`.
* When a downlink is received, the packet forwarder schedules it in an internal queue system to be handled **100ms before `ExpectedSendingTimestamp`**. This means that the packet forwarder has then 100ms to perform its last computations on the downlink packet and to transmit it. This 100ms margin value is called `sendingTimeMargin`.

* The value of `sendingTimeMargin` has a consequence of the gateway's downlink debit rate. Considering we need 20ms to transmit a downlink from the gateway's internal memory to emission, it means that we can only reasonably transmit 3000 downlinks per minute - and that is making the assumption that receive windows won't overlap.
* The value of `sendingTimeMargin` has a consequence of the gateway's downlink debit rate. Considering we need 100ms to transmit a downlink from the gateway's internal memory to emission, it means that we can only reasonably transmit 600 downlinks per minute - and that is making the assumption that receive windows won't overlap.

* Having a 20ms `sendingTimeMargin` allows the packet forwarder to have a comfortable margin in case of performance issues on the system, or in case of transmission issues. For systems connected to a concentrator via USB, it usually takes 10ms to perform the last computations and to transmit the packet to the concentrator. However, one improvement to the packet forwarder would be setting `sendingTimeMargin` as a build or run parameter, to make use of the higher transmission speeds on SPI-connected devices.
* Having a 100ms `sendingTimeMargin` allows the packet forwarder to have a comfortable margin in case of performance issues on the system, or in case of transmission issues. For systems connected to a concentrator via USB, it usually takes 10ms to perform the last computations and to transmit the packet to the concentrator. However, one improvement to the packet forwarder would be setting `sendingTimeMargin` as a build or run parameter, to make use of the higher transmission speeds on SPI-connected devices.

*Note:* The packet forwarder doesn't support GPS concentrators yet. GPS concentrators don't rely on an internal clock, and are able to transmit absolute timestamps for an uplink - meaning it is not necessary to know their internal clock value to transmit downlinks to such devices.

Expand Down
76 changes: 76 additions & 0 deletions docs/INSTALL_INSTRUCTIONS/IMST_RPI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Install the TTN Packet Forwarder on a Raspberry Pi with an IMST ic880a board

To follow this manual, you must have a Raspberry Pi with an IMST ic880a board, connected through SPI.

## Download and run

1. Download the [Raspberry Pi + IMST build](https://ttnreleases.blob.core.windows.net/packet_forwarder/master/imst-rpi-pktfwd.zip) of the packet forwarder.

2. Configure the packet forwarder:

```bash
$ <packet-forwarder-binary> configure
[...]
INFO New configuration file saved ConfigFilePath=/root/.pktfwd.yml
```

3. Run the packet forwarder:

```bash
$ <packet-forwarder-binary> start
```

### Permanent installation with systemd

If you want a permanent installation of the packet forwarder on your Raspberry Pi, with `systemd` managing the packet forwarder on the background, we provide a basic systemd installation script, `install-systemd.sh`.

1. Select the build, and copy it in a permanent location - such as `/usr/bin`.

2. Create a configuration file in a permanent location, such as in a `/usr/config` directory:

```bash
$ touch /usr/config/ttn-pkt-fwd.yml
```

3. Set up this configuration file:

```bash
$ <packet-forwarder-binary> configure /usr/config/ttn-pkt-fwd.yml
```

4. Use the `install-systemd.sh` script, with the binary as a first argument and the config file as a second argument:

```bash
$ ./install-systemd.sh <packet-forwarder-binary-path> <configuration-file-path>
./install-systemd.sh: Installation of the systemd service complete.
```

5. Reload the systemd daemon, and start the service:

```bash
sudo systemctl daemon-reload
sudo systemctl enable ttn-pkt-fwd
sudo systemctl start ttn-pkt-fwd
```

## <a name="build"></a>Build

If want to contribute to the development of the packet forwarder, you might want to build the TTN Packet Forwarder. You will need to use a Linux environment to run the toolchain necessary for the build.

### Getting the toolchain

If you want to build the packet forwarder for a Raspberry Pi, you will need a **Raspberry Pi cross-compiler**. On some Linux distributions, such as Ubuntu, a toolchain is available as a package: `sudo apt install gcc-arm-linux-gnueabi -y`.

### Building the binary

Make sure you have [installed](https://golang.org/dl/) and [configured](https://golang.org/doc/code.html#GOPATH) your Go environment.

Follow these commands:

```bash
$ make dev-deps
$ make deps
$ GOOS=linux GOARCH=arm GOARM=7 CC=gcc-arm-linux-gnueabi make build
```

The binary will then be available in the `release/` folder.
16 changes: 9 additions & 7 deletions docs/INSTALL_INSTRUCTIONS/KERLINK.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
Before installing the TTN Packet Forwarder, we recommend **updating the Station to the latest firmware available**.

+ [Download and test the TTN Packet Forwarder](#download-test)
+ [Install the TTN Packet Forwardeer](#install)
+ [Install the TTN Packet Forwarder](#install)
+ [Build the TTN Packet Forwarder](#build)
+ [Troubleshooting](#troubleshooting)

## <a name="download-test"></a>Download and test the TTN Packet Forwarder

*Note: Before installing the new packet forwarder, make sure you removed any other packet forwarder installed on your Kerlink IoT Station. If you don't have any important files stored on the disk, the safest way to make sure of that is to update the Station to the latest firmware available, which will reset the file system in the process.*

1. Download the [Kerlink build](https://ttnreleases.blob.core.windows.net/packet_forwarder/master/kerlink-iot-station-pktfwd.zip) of the packet forwarder.

2. In the folder, you will find several files: a `create-kerlink-package.sh` script and a binary file, that we will call `packet-forwarder`.
2. In the folder, you will find several files: a `create-package.sh` script and a binary file, that we will call `packet-forwarder`.

The binary is sufficient for a testing use - if you wish to try the TTN packet forwarder, just copy the binary on the Station, and execute:

Expand All @@ -34,19 +36,19 @@ This section covers permanent installation of the TTN Packet Forwarder on a Kerl

### Packaging the TTN Packet Forwarder

Download the [Kerlink build](https://ttnreleases.blob.core.windows.net/packet-forwarder/master/kerlink-iot-station-pktfwd.zip) of the packet forwarder. Execute the `create-kerlink-package.sh` script with the binary inside as an argument:
Download the [Kerlink build](https://ttnreleases.blob.core.windows.net/packet-forwarder/master/kerlink-iot-station-pktfwd.tar.gz) of the packet forwarder. Execute the `create-package.sh` script with the binary inside as an argument:

```bash
$ ./create-kerlink-package.sh packet-forwarder
$ ./create-package.sh packet-forwarder
[...]
# The script will ask you several questions to configure the packet forwarder.
./create-kerlink-package.sh: Kerlink DOTA package complete.
./create-package.sh: Kerlink DOTA package complete.
```

A `kerlink-release` folder will appear in the folder you are in:
A `kerlink-release-<id>` folder will appear in the folder you are in:

```bash
$ cd kerlink-release && tree
$ cd kerlink-release-<id> && tree
.
├── dota_ttn-pkt-fwd.tar.gz
├── INSTALL.md
Expand Down
22 changes: 16 additions & 6 deletions docs/INSTALL_INSTRUCTIONS/MULTITECH.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@

## Download and install

1. Download the [Multitech Conduit package](https://ttnreleases.blob.core.windows.net/packet_forwarder/master/multitech-conduit-pktfwd.zip) of the packet forwarder.
*Note: Before installing the new packet forwarder, make sure you removed any other packet forwarder installed on your Multitech Conduit.*

2. In the archive, you will find an `.ipk` file, as well as the executable binary. Unless you want to test the packet forwarder before installing it, you won't need to use the binary. Copy the `.ipk` file on the Multitech mConduit, using either a USB stick or through the network.
1. Download the [Multitech Conduit package](https://ttnreleases.blob.core.windows.net/packet_forwarder/master/multitech-conduit-pktfwd.tar.gz) of the packet forwarder.

3. Install the package, configure the packet forwarder, then start it:
2. In the archive, you will find an `create-package.sh` file, a `multitech-installer.sh`, as well as the executable binary. Execute the `create-package.sh` file, with the binary as a first argument:

```bash
$ ./create-package.sh <packet-forwarder-binary>
[...]
# Following the instructions of the wizard
./create-package.sh: package available at ttn-pkt-fwd.ipk
```

3. Copy the package on the Multitech Conduit, using either a USB key or `scp` if you have an SSH connection to the Multitech Conduit. Install the package, configure the packet forwarder, then start it:

```bash
$ opkg install ttn-pkt-fwd.ipk
Expand Down Expand Up @@ -63,12 +72,13 @@ The binary will then be available in the `release/` folder.

### Building the package

To build the package, use the `create-kerlink-package.sh` script:
To build the package, use the `scripts/multitech/create-package.sh` script:

```bash
$ ./scripts/create-kerlink-package.sh release/packet-forwarder-linux-arm-multitech-ftdi
$ ./scripts/multitech/create-package.sh release/<packet-forwarder-binary>
[...]
./scripts/create-kerlink-package.sh: package available at ttn-pkt-fwd-multitech.ipk
# Following the instructions of the wizard
./create-package.sh: package available at ttn-pkt-fwd.ipk
```

The package will then be available at the specified path.
Loading

0 comments on commit 2ac53a3

Please sign in to comment.