Setting up a Private Routing Environment

Hello,

I have recently installed a private TTN backend and I want to check everything is fine.
I have not gateway or device linked to my private network yet.
I’m looking for a simple procedure to send or receive data without hardware in order to validate the backend software installation.
I tried to send data with ttnctl devices simulate but this needs a registered device.

In the same way i’m looking for a way to monitor my backend in case of failure in one of the components.

Do you knwo some tools or a simple way to do that ?
Regards

Hi all,

I would also be very interested in what bouchezb is asking above.
At the moment we have a private backend set up and we are trying to check it using real devices. However, we are facing some problems:
Using the Semtech packet forwarder in our gateway, I can see packets arriving at the Bridge server using the docker-compose logs. However, the Router server (I use mynetwork-router as ID) fails to forward the messages to the Broker. The DEBUG logs from the Router’s container are:

DEBUG rpc-client: call failed auth-type=token duration=1.048007ms error=rpc error: code = PermissionDenied desc = permission denied: unable to parse token: Auth server mynetwork-router not registered id=mynetwork-router method=/discovery.Discovery/AddMetadata service-name=router service-version=v2.9.0-dev-0c455d496d53c849bed3cac3b794ae51fa514e19 (2017-10-11T11:10:16Z)
and
DEBUG No brokers to forward message to ADR=true ADRAckReq=false Ack=false AppPayloadSize=12 Confirmed=false DataRate=SF7BW125 DevAddr=26010E32 DownlinkOptions=2 FCnt=13124 FPending=false FPort=1 Frequency=867300000 GatewayID=eui-b827ebfffe2fe441 Modulation=LORA PayloadSize=25 RSSI=-66 SNR=9.2

Is this an access token issue of the Router server? I mean, it seems the Router tries to access the AddMetadata function of the Discovery server but it fails because of a token error. I am confused as there is also a registration error mentioned in the same debug message regarding mynetwork-router. Where was the router supposed to be registered and isn’t? I am using ttn’s account server I have set up the backend using the instructions at https://www.thethingsnetwork.org/article/deploying-a-private-routing-environment-with-docker-compose.

FYI, I have also tried the ttn packet forwarder but it just hangs at the point it tries to connect to the Router after it successfully retrieves the router id from the Discovery server. I have noticed the notification about ttn pcket forwarder so for now I will assume that it just doesn’t work and I shouldn’t be using it anyway.

I would appreciate any pointer or advice because we are really stuck at this point. We already have a couple of gateways and sensors and we cannot get the data through…

–Yannis

Hey @Gig,
can you tell me, how you made the whole backend run on a RPi with gateway software?
I´m not sure, which tutorial i should use. Docker or localhost?

There are a few other questions i have.
Is Go Language needed?
How do i install the ttn master branch on Raspbian Jessie?
How can i configure the ttn.yml files for the different servers?

Thanks a lot.

I try to generate prefix with the command “broker register-prefix 26000000/20”.

But I get an error like this: error=permission denied: unable to parse token: Auth server mynetwork-networkserver not registered.

Also in the broker/ttn.yml they talk about the THE DISCOVERY ACCESS TOKEN THAT YOU GENERATED FOR THE **BROKER**. When is this generated?

Hi
I was trying to setup TTN private network locally , but while starting discovery server by using
ttn discovery --config ./discovery/ttn.yml, i got following error.

FATAL Error in gRPC proxy error=listen tcp 0.0.0.0:8080: bind: address already in use

My ttn.yml file follows …

id: mynetwork-discovery
tls: true
key-dir: discovery/
auth-servers:
ttn-account-v2: "https://account.thethingsnetwork.org"
local: “file://discovery/server.pub”

discovery:
master-auth-servers:

  • ttn-account-v2
  • local

Hi

I follow this guide to install my TTN private network.
I try to connect http://discovery.thethingsnetwork.org:8080 or server_ip:8080 with my browser. It display “Not Found” at the left upper corner.
I don’t understand why i don’t see the same page of TTN public network.

thanks.

sure your server is running ?

I suppose.
I run all
ttn discovery --config discovery/ttn.yml
ttn router --config router/ttn.yml
ttn networkserver --config networkserver/ttn.yml
ttn broker --config broker/ttn.yml
ttn handler --config handler/ttn.yml
gateway-connector-bridge --root-ca-file “bridge/ca.cert” --ttn-router “localhost:1900/mynetwork-router”

and i have no error.
How can i test if my server is running?

There is no webpage included in the backend, just an API. You can find the api methods in our api repository on Github (https://github.com/TheThingsNetwork/api/blob/master/discovery/Discovery.md for example) or in the Learn section of TheThingsNetwork.org. To interact with your private backend you can use ttnctl.

Ok, thanks you. I didn’t understand this part.

Hi,

I am running though

https://www.thethingsnetwork.org/article/setting-up-a-private-routing-environment
https://www.thethingsnetwork.org/article/deploying-a-private-routing-environment-with-docker-compose

and trying to to get things to work within Openshift/Kubernetes .

Things seemed to have one reasonably OK but I am getting a message in the handler logs which looks like an error although categorized as DEBUG

DEBUG ccResolverWrapper: sending new addresses to cc: [{handler:1904 0 }]
DEBUG pickfirstBalancer: HandleSubConnStateChange: 0xc4208a92b0, CONNECTING
DEBUG grpc: addrConn.createTransport failed to connect to {handler:1904 0 }. Err :connection error: desc = “transport: Error while dialing dial tcp 172.30.53.138:1904: i/o timeout”. Reconnecting…
DEBUG pickfirstBalancer: HandleSubConnStateChange: 0xc4208a92b0, TRANSIENT_FAILURE

I can do a curl etc from a different pod so I can’t see how how the network connectivity is a problem?

I have a similar problem that I believe is caused by our ISP messing with the TLS Handshaking traffic.

The same code works perfectly on an AWS EC2 instance, via a mobile hotspot and on my home ADSL connection, just the office connection fails (ISP - Virgin Business UK) with the same error as you.

Tests from the office bypassing all our firewalls etc (yes curl worked for me as well), always fail to get a response from the grpc calls, however other ISPs work fine.

I see it’s a private 172 address - but I suspect there may be some ports being blocked (?) on your network.

Thanks for the info.

I’ve created a deployment config for Openshift which puts all the containers into a single pod (this isn’t going into production so being able to individually scale different components isn’t an issue!) This basically mimics the first private network document of Hylke Visser.

This results in a successful deployment so far. Intend to verify with ttnctl shortly.

Hi - I am trying to verify a private network in the absence of an actual gateway.

I am not convinced that ttnctl is verifying enough, I get the impression that it is just accessing the mqtt message broker not the ttn broker component and certainly not the router.

I was given hope looking at

https://www.thethingsnetwork.org/docs/gateways/start/connection.html#example-using-grpc

But trying to build the Golang above but I think it is out of date and is based on old ttn go lang libaries (?)

Also I am new to Golang so any hints help would be appreciated

Here is the output of the go build

[pfry@pfry all-in-one]$ go build routerTest.go

command-line-arguments

./routerTest.go:24:20: cannot use *gateway.RxMetadata literal (type *gateway.RxMetadata) as type gateway.RxMetadata in field value
./routerTest.go:25:11: unknown field ‘Rssi’ in struct literal of type gateway.RxMetadata
./routerTest.go:26:10: unknown field ‘Snr’ in struct literal of type gateway.RxMetadata
./routerTest.go:29:21: cannot use *protocol.RxMetadata literal (type *protocol.RxMetadata) as type protocol.RxMetadata in field value
./routerTest.go:30:18: undefined: protocol.RxMetadata_Lorawan
./routerTest.go:51:27: undefined: discovery.NewClient
./routerTest.go:51:90: unknown field ‘Id’ in struct literal of type discovery.Announcement
./routerTest.go:63:19: undefined: router.NewRouterClientForGateway
./routerTest.go:63:75: undefined: c
./routerTest.go:64:19: undefined: router.NewMonitoredUplinkStream
./routerTest.go:64:19: too many errors
[pfry@pfry all-in-one]$ go version
go version go1.9.2 linux/amd64

I have tried to fix the issues that are obvious (upper case field names etc) but am left with

./routerTest.go:24:20: cannot use gateway.RxMetadata literal (type *gateway.RxMetadata) as type gateway.RxMetadata in field value
./routerTest.go:29:21: cannot use protocol.RxMetadata literal (type *protocol.RxMetadata) as type protocol.RxMetadata in field value
./routerTest.go:51:27: undefined: discovery.NewClient
./routerTest.go:63:19: undefined: router.NewRouterClientForGateway
./routerTest.go:63:75: undefined: c
./routerTest.go:64:19: undefined: router.NewMonitoredUplinkStream

When I start the local discovery server I get the following:

./ttn-linux-amd64 discovery --config ./discovery/ttn.yml
Using config file: ./discovery/ttn.yml
INFO Initializing The Things Network Auth Servers=map[ttn-account-v2:https://account.thethingsnetwork.org local:file://discovery/server.pub] ComponentID=mynetwork-discovery Description= Discovery Server Address:1900=discover.thethingsnetwork.org Monitors=map
INFO Initializing Discovery Database=localhost:6379/0 HTTP Proxy=0.0.0.0:8080 Server=0.0.0.0:1900
INFO Starting
INFO ttn: Got public keys for token validation

I am suspecting there is an issue with the discovery server address setting there.

How did you get resolved? I have the same issue…

Alex

can we bypass fare usage policy by setting up private environment ???

As much as anything ‘fair use’ is about utilisation & saturation of the available RF spectrum…every GW in range receives all packets irrespective of network used and it is only when data gets to back end that policy is enforced and packets dropped. Having a private environment doesnt resolve the spectrum problem so short answer is no - (also) you still need to follow ETSI/FCC or who ever rules (in your part of the world) wrt duty cycle/dwell times etc. and fair use, whilst tighter than regs, ensures fair use for all…

‘Bypassing’ is somewhat antisocial…(IMHO) - though occasional ‘excess’ for testing & commissioning will usually see a blind eye turned…

:wink: :sunglasses:

1 Like

TTN’s fair access policy only applies to the public community network, and is there to ensure that everyone can enjoy the public resources that are provided for free by the community. If you have your own private network with your own gateways, you can use them as much as you want, as long as you comply with the local duty cycle, transmit power or dwell time regulations. Having a private network does not except you from those. TTN’s backend will not help you break the law. If you use our backend in your private network, it will not be possible to circumvent those regulations.

One last thing: If you run into these limitations with your use case, then LoRaWAN is probably not a suitable technology for your use case, and you may want to consider alternatives such as Bluetooth/Wifi or 3G/4G/LTE/…

Hello,
we have set up a local backend on a Raspberry Pi3 which seems to be running fine on localhost (no Docker). Now we also have a TTN Gateway here which we would like to connect to this private backend. With the ttnctl-CLI one can set the address of the router for the gateway (something like: ttnctl gateways edit MYGATEWAY_ID --router 192.168.2.22).
Now the question is: Is it sufficient to set the router-address in the gateway to the IP of the Raspberry-backend (e.g. 192.168.2.22.) or is there more that has to be done?
I have tried to setup the whole backend using the IP of the Raspberry instead of localhost and set this address in the TTN gateway. The gateway seems to get the new address after a restart, but it will fail to connect to anything except the official routers (e.g. ttn-eu-router). The necessary ports (1900 - 1904 I think) were open, as I could verify with another Raspberry in the Ethernet.

Are we thinking to simple there, did we miss something, or is the TTN gateway not intended to work with private backends at all?
I highly appreciate your help!

Regards,

Flo

To give the answer myself:

First of all: If you want to use a private, local backend, it’s probably much easier to use a gateway different to TheThings Gateway. You can use the TTN Gateway plug-n-play to connect with the worldwide TTN (for noobies) or go the full on nerdy way, but nothing in between. Nerds can go on reading …

The problem is the TheThings Gateway and/or TheThings Console-WebGUI. In the firmware code on GitHub and in particular in app_configuration.c there is code that will force the gateway to load it’s configuration from the account server (default: account.thethingsnetwork.org). Now you can either (somehow) program your own account server and set it in the gateway or you can use the (closed-source) TTN account server. The problem now is, that the account server or the TTN Console-WebGUI refuses to accept routers other than the official TTN routers, so the Gateway will not get your local router’s adress, if you set it on the WebGUI.
The solution (or at least my solution) was to reprogram the gateways firmware (which is open-source and available on Github) and hard-code my local router’s IP-address.

In app_configuration.c search for:
int r = EXIT_FAILURE; _ f(strstr(response_code, "200") != NULL) { // Success SYS_DEBUG(SYS_ERROR_DEBUG, "CONF: Response: too much to print\r\n"); SYS_DEBUG(SYS_ERROR_DEBUG, "CONF: Stack size 1: %d\r\n", uxTaskGetStackHighWaterMark(NULL)); r = _parseSettings(request.data_buffer); SYS_DEBUG(SYS_ERROR_DEBUG, "CONF: Stack size 2: %d\r\n", uxTaskGetStackHighWaterMark(NULL)); if(r == EXIT_SUCCESS) appConfigurationData.state = APP_CONFIGURATION_VALIDATING; else appConfigurationData.state = APP_CONFIGURATION_INCOMPLETE; }

The decoding of the HTTP request to the activation server happens in _parseSettings(request.data_buffer). So afterwards you can just force the gateway to reject the configuration from the activation server and set:

const char nhost = "YOUR_BACKENDS_IP-ADDRESS"
const char npath = "";
bool tls = false; //true
uint16_t nport = 1883; //8883 if you need TLS encryption of MQTT_
                       sprintf(appGWActivationData.configuration_gateway.ttn_servers[0].server_address, "%s%s", nhost,
                                npath);
                        appGWActivationData.configuration_gateway.ttn_servers[0].serv_port_up   = nport;
                        appGWActivationData.configuration_gateway.ttn_servers[0].serv_port_down = nport;
    appGWActivationData.configuration_gateway.ttn_servers[0].serv_tls = tls;

To setup your development environment see the instructions at:
https://github.com/TheThingsProducts/gateway/tree/develop/firmware
https://www.thethingsnetwork.org/forum/t/building-the-ttn-gateway-firmware-from-the-github-code/12739
To update the firmware via SD-card, compile your new firmware with MPLABX and run generate_hex_with_checksum.sh in the TTN firmware folder.
For programming the gateway with a PickIt or ICD3 debugger see https://www.thethingsnetwork.org/docs/gateways/gateway/programhexfile.html.
For debugging, be sure to modify the reset vector in the linker file (still does not work flawlessly, resets at start of RTOS scheduler, don’t know why):
RESET_ADDR = 0xBFC00000 //NOT 0xBD000000, works only with bootloader in non-debugging state

Btw: It is sufficient to setup your local backend according to Hylke Visser’s guide. The gateway will finally connect to mosquitto and the gateway-bridge. The bridge will then forward the gateways data to the router and there you go. Be sure to only use ttnctl-CLI-tool for your local backend and not the WebGUI.