The Things Network 笔记

Install

Community

Download

1
2
3
4
5
## 
git clone https://github.com/TheThingsNetwork/lorawan-stack.git

## install
https://www.thethingsindustries.com/docs/getting-started/installation/

Certificates

ca.json

1
2
3
4
5
{
"names": [
{"C": "NL", "ST": "Noord-Holland", "L": "Amsterdam", "O": "The Things Demo"}
]
}

Generate:

1
cfssl genkey -initca ca.json | cfssljson -bare ca

cert.json

change host

1
2
3
4
5
6
{
"hosts": ["thethings.example.com"],
"names": [
{"C": "NL", "ST": "Noord-Holland", "L": "Amsterdam", "O": "The Things Demo"}
]
}

Generate:

1
cfssl gencert -ca ca.pem -ca-key ca-key.pem cert.json | cfssljson -bare cert

Configuration Cert

  • docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    # If using custom certificates:
secrets:
- ca.pem
- cert.pem
- key.pem

# If using custom certificates:
secrets:
ca.pem:
file: ./ca.pem
cert.pem:
file: ./cert.pem
key.pem:
file: ./key.pem
  • ttn-lw-stack-docker.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# If using custom certificates:
tls:
source: file
root-ca: /run/secrets/ca.pem
certificate: /run/secrets/cert.pem
key: /run/secrets/key.pem

# Let's encrypt for "thethings.example.com"
# tls:
# source: 'acme'
# acme:
# dir: '/var/lib/acme'
# email: 'you@thethings.example.com'
# hosts: ['thethings.example.com']
# default-host: 'thethings.example.com'

Up

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
docker-compose pull
docker-compose run --rm stack is-db init
docker-compose run --rm stack is-db create-admin-user --id admin --email your@email.com

docker-compose run --rm stack is-db create-oauth-client \
--id cli \
--name "Command Line Interface" \
--owner admin \
--no-secret \
--redirect-uri "local-callback" \
--redirect-uri "code"


# see config/stack/ttn-lw-stack-docker.yml
CONSOLE_SECRET="console"
SERVER_ADDRESS="dev:1885"

docker-compose run --rm stack is-db create-oauth-client \
--id console \
--name "Console" \
--owner admin \
--secret "${CONSOLE_SECRET}" \
--redirect-uri "${SERVER_ADDRESS}/console/oauth/callback" \
--redirect-uri "/console/oauth/callback" \
--logout-redirect-uri "${SERVER_ADDRESS}/console" \
--logout-redirect-uri "/console"

Override

Things Stack 是一个实现 LoRaWAN 协议的网络服务器。

什么是 Things Stack?

The Things Stack是企业级的 LoRaWAN 网络服务器,建立在开源核心之上。Things Stack允许您在自己的硬件或云上构建和管理 LoRaWAN 网络。

  • TTS 是 The Things Stack, LoRaWAN Network Server Stack。Things Stack 目前是网络服务器实现的版本3,因此也被非正式地称为V3。

  • TTN 是 “物联网”(The Things Network),它是一个全球协同物联网生态系统,使用 LoRaWAN 创建网络、设备和解决方案。The Things Network 运行着 The Things Stack Community Edition,这是一个众包、开放和去中心化的 LoRaWAN 网络。这个网络是一个很好的开始测试设备、应用程序和集成,并熟悉 LoRaWAN 的方法。

  • TTI 是 The Things Industries:该公司主要负责The Things Stack 的开发和文档编写。Things Industries 还提供具有额外企业功能的云托管和本地私有 LoRaWAN 网络,以及针对企业客户的高级支持计划。

Command-Line Interface

Console

控制台是 LoRaWAN 的 Things Stack 的管理应用程序。它是一个 Web 应用程序,可以用来注册应用程序,终端设备或网关,监控网络流量,或配置网络相关选项等。

API

Gateway Server MQTT

MQTT 协议可用于开发自定义包转发器或网关桥接器,用于在网关和 The Things Stack 之间交换流量,或用于测试目的,方便地模拟网关流量。它是一个替代 Basic Station 和 Semtech UDP协议。

MQTT 是用于交换消息的服务器-客户机协议。客户端可以连接到服务器并发布特定主题下的消息(数据)。它们还可以订阅一个主题,从而接收在该主题下发布的所有消息(由其他客户机或MQTT服务器本身发布)。

网关服务器是 MQTT 服务器,网关作为 MQTT 客户端连接到网关服务器。连接的网关由用于身份验证的用户名标识。

Protocol Buffers

为了与 MQTT 协议通信,网关服务器和网关正在交换 Protocol Buffers。https://github.com/TheThingsNetwork/lorawan-stack/blob/v3.13/api/lorawan.proto

Connecting to the Gateway Server

通过身份验证的客户端可以只写访问以下主题:

  • v3/< Gateway -id>@/up:用于向网关服务器发送上行流量。
  • v3/@/status:向网关服务器发送网关状态消息。
  • v3/< Gateway -id>@/down/ack:用于向网关服务器发送TxAck消息。

客户端也获得只读访问,并应该订阅以下主题:

  • v3/< Gateway -id>@/down:网关服务器发布网关应该发送的下行消息。
1
2
3
4
5
6
$ export GATEWAY_ID="test-gtw@my-tenant"
$ export GATEWAY_API_KEY="NNSXS.VEEBURF3KR77ZR..." # API key with RIGHT_GATEWAY_LINK rights
$ mosquitto_pub \
-h "thethings.example.com" -p 1882 \
-u "$GATEWAY_ID" -P "$GATEWAY_API_KEY" \
-t "v3/$GATEWAY_ID/up" -f test-uplink-message
1
2
3
4
5
6
$ export GATEWAY_ID="test-gtw@my-tenant"
$ export GATEWAY_API_KEY="NNSXS.VEEBURF3KR77ZR..." # API key with RIGHT_GATEWAY_LINK rights
$ mosquitto_sub \
-h "thethings.example.com" -p 1882 \
-u "$GATEWAY_ID" -P "$GATEWAY_API_KEY" \
-t "v3/$GATEWAY_ID/down" -v

Gateway Status Messages

1
2
3
4
5
6
$ export GATEWAY_ID="test-gtw@my-tenant"
$ export GATEWAY_API_KEY="NNSXS.VEEBURF3KR77ZR..." # API key with RIGHT_GATEWAY_LINK rights
$ mosquitto_pub \
-h "thethings.example.com" -p 1882 \
-u "$GATEWAY_ID" -P "$GATEWAY_API_KEY" \
-t "v3/$GATEWAY_ID/status" -f test-gateway-status

TxAck Messages

1
2
3
4
5
6
$ export GATEWAY_ID="test-gtw@my-tenant"
$ export GATEWAY_API_KEY="NNSXS.VEEBURF3KR77ZR..." # API key with RIGHT_GATEWAY_LINK rights
$ mosquitto_pub \
-h "thethings.example.com" -p 1882 \
-u "$GATEWAY_ID" -P "$GATEWAY_API_KEY" \
-t "v3/$GATEWAY_ID/down/ack" -f example-tx-ack

Working with Events

Things Stack 生成大量的事件,让你能够洞察正在发生的事情。可以订阅应用程序、网关、终端设备事件,以及用户、组织和 OAuth 客户端事件。

CLI

1
ttn-lw-cli events subscribe --gateway-id gtw1 --application-id app1

HTTP

1
2
3
4
5
6
7
8
9
10
11
12
# create api key token
ttn-lw-cli users api-key create \
--user-id admin \
--right-application-all \
--right-gateway-all

# subscribe stream
curl https://thethings.example.com/api/v3/events \
-X POST \
-H "Authorization: Bearer NNSXS.BR55PTYILPPVXY.." \
-H "Accept: text/event-stream" \
--data '{"identifiers":[{"application_ids":{"application_id":"app1"}},{"gateway_ids":{"gateway_id":"gtw1"}}]}'

Components

Application Server

Application Server 处理 LoRaWAN 应用层,包括上行数据的解密和解码、下行队列和下行数据的编码和加密。

它托管一个用于流媒体应用程序数据的MQTT服务器,支持HTTP webhook以及发布/订阅集成。

应用程序可以通过多种协议和机制连接到 Application Server。

  • MQTT Protocol

应用程序可以通过 MQTT 交换 JSON 消息来连接到应用服务器。MQTT 在 TLS 上可用,为应用程序和应用服务器之间交换的消息提供机密性。

上行消息不仅包含数据上行消息,而且还包含不同主题的 join-accept 和 downlink 事件。

  • HTTP Webhooks

应用程序可以通过 HTTP webhook 获取流 JSON 消息,并通过向应用服务器发出 HTTP 请求来调度下行消息。

与 MQTT 一样,可以配置所有上游消息,包括上行消息、加入接收事件和下行事件,每个都用于分隔 URL 路径。

  • Pub/Sub Integrations

应用程序还可以使用发布/订阅集成来处理流数据。这包括连接到外部 MQTT 服务器和 NATS 服务器。

  • Message Processing

Application Server 可以解码和编码由终端设备发送和接收的二进制有效负载。这允许使用结构化流数据,例如使用 MQTT 和 HTTP Webhook 的JSON对象,同时使用通过无线电传输的压缩二进制数据。

消息处理器可以是众所周知的格式或自定义脚本,可以在设备级别或针对整个应用程序进行设置。

Network Server

Network Server 负责处理 LoRaWAN 网络层,包括 MAC命令、区域参数和自适应数据速率(ADR)。

Device Management

网络服务器为终端设备(End-Device)管理公开了 NsEndDeviceRegistry 服务。该服务的典型客户端有 Console 和 CLI。

网络服务器存储设备 MAC 配置、MAC状态 和网络会话密钥。

设备MAC配置变化可能会触发下行报文。

网络服务器允许应用服务器推送、替换和列出应用下行链路,以及通过 gRPC API 链接应用。

改变应用程序下行队列可能会触发下行消息。

一旦链接建立,Network Server 将通过该链接向客户端发送特定于应用程序的上行消息。每个应用程序最多只能有一个活动链接。

如果链接不是活动的,但是 Network Server 有特定于应用程序的上行消息要发送,这些消息将在链接建立后排队并发送。

网络服务器维护内部下行任务队列。每个下行任务都有一个与之相关的执行时间,这些任务按升序排列。每当下行任务准备执行时,它就会尽快执行。

Join-accept

如果存在一个挂起的会话,并且为该设备排队加入join-accept,它将被调度。

如果一个挂起的会话不存在或已经发送了 Join-accept, Network Server 将尝试在活动会话中生成并调度数据下行。

网络服务器通过 gRPC 从网关服务器接收上行链路。

网络服务器对接收到的上行链路进行处理。第一步是将上行链路与设备匹配。如果上行链路不能与网络服务器中存储的设备匹配,则丢弃上行链路。

Join-Request

如果收到 Join-request:

  1. 设备使用连接请求中出现的 DevEUI和 JoinEUI 对进行匹配,这是唯一标识设备的。
  2. 新的 DevAddr 被分配给设备,新的 MAC 状态被派生出来。
  3. 如果集群中存在 Join Server, Network Server 将向集群本地 Join Server 发送一个Join请求消息。
  4. 如果集群中不存在 Join Server,或者设备没有在集群本地 Join Server 中提供,网络服务器将向通过互操作性配置发现的 Join Server 发送一个 Join 请求消息。
  5. 如果一个 Join Server 接受了Join-request,设备可能会排队接收 Join-accept 消息,并向链接的 Application Server 发送特定于应用程序的上行消息,这些上行消息携带有关Join-accept 的信息。

如果收到数据上行:

  1. 使用数据上行链路中存在的 DevAddr 匹配设备。通过比较会话上下文和 MAC 状态进行匹配,并进行 MIC 检查。由于多个设备可能具有相同的 DevAddr,网络服务器在匹配设备之前可能需要通过多个存储设备。
  2. 网络服务器处理 MAC 命令,如果这样的命令存在于帧中,并相应地更新 MAC 状态。
  3. 如果数据上行配置了ADR 位,Network Server 运行 ADR 算法,更新 MAC 状态。
  4. 如果数据上行链路处理成功,下行链路可能会为设备排队,一个或多个特定于应用程序的上行消息携带有关 Join-accept 的相关信息被发送到链接的应用服务器。

Identity Server

身份服务器提供了存储实体(如应用程序及其终端设备、网关、用户、组织、OAuth客户端和身份验证提供者)的注册中心。它还通过成员关系和API键管理访问控制。

Entity Registries

实体注册中心存储关于 Things Stack 中所有主要实体的公共信息。这包括名称、描述和属性(用户定义的键值对)。

Users

在 Identity Server 中注册的第一个实体通常是管理用户。用户可以通过提供电子邮件地址并选择用户ID和密码进行注册。这些信息以后可以用于登录。

用户ID是用户的唯一标识符。用户 ID 与组织 ID 在同一个命名空间中。这意味着不可能创建与现有组织具有相同ID的用户。出于安全原因,也不可能重用已删除用户或组织的ID。

用户可以是“admin”,这给了他们更高的权限。正常的注册过程不允许用户注册为 admin,这就是为什么入门指南使用不同的命令创建admin用户。

用户可以处于多个状态之一:请求、批准、拒绝、挂起等。用户的状态决定了用户是否能够执行操作,以及哪些操作。正常情况下,用户处于“批准”状态。如果 The Things Stack 被配置为需要新用户的管理批准,那么用户最初处于“请求”状态,管理用户可以将其更新为“批准”或“拒绝”状态。如果用户行为不当,也可能被管理员挂起。

Gateways

网关可以通过选择一个ID和可选地注册网关的EUI来注册。注册后,可以创建一个API密钥;网关可以使用它的ID(或EUI)和API密钥一起使用 The Things Stack 进行身份验证。

为了保证网关的正常运行,需要设置频率规划ID,并设置网关是否需要满足占空比。

如果网关能够与网关配置服务器通信,则可以在网关注册表中设置网关服务器地址和固件更新设置。

网关注册表还存储有关网关天线的信息,如位置和增益。

Applications

应用程序用于在一个地方组织多个终端设备的注册和流量。应用程序通常对应于处于相同部署或相同类型的终端设备集合。

End Devices

Identity Server 中的终端设备注册表只存储终端设备的元数据,允许 Console 和 CLI 等客户端在应用程序中列出终端设备。它通常存储有关终端设备的品牌、模型、硬件、固件和位置的元数据。它还存储了 Network Server、Application Server 和Join Server的地址,以便 Console 和 CLI 等客户机知道存储终端设备的其他属性的位置。

Organizations

组织用于创建多个用户组,并方便地为整个用户组分配权限。

组织ID是组织的唯一标识符。组织id与用户id在相同的命名空间中。这意味着不可能创建具有与现有用户相同ID的组织。出于安全原因,也不可能重用已删除用户或组织的ID。

OAuth Clients

可以在 OAuth 注册表中注册外部 OAuth 客户端。OAuth 客户端使用客户端ID和秘密进行注册。

与用户一样,OAuth客户机可以处于多种状态中的一种。非admin用户创建的OAuth客户端需要admin用户审批。

官方的OAuth客户端可以被标记为“背书”,或者可以为所有用户预先授权。

Authentication Providers

联邦身份验证提供者可以在身份验证提供者注册中心中注册。身份验证提供者使用ID、名称和提供者配置注册。

身份验证提供者用于允许 Identity Server 从外部身份提供者(如OpenID Connect提供者)获得用户的身份。

Entity Access

标识服务器负责对实体的访问控制。

Memberships

成员资格定义了用户或组织对另一个实体拥有的权利。最简单的成员关系是用户是应用程序或网关的直接成员(或合作者)。成员资格的权限表明允许用户对应用程序或网关做什么。

间接成员关系是指用户是某个组织的成员,而该组织是某个应用程序或网关的成员。在这种情况下,用户-组织成员关系的权限与组织-应用或组织-网关成员关系的权限相交,计算出该用户的有效权限。

API Keys

对于大多数实体,都可以创建API Keys。这些 API Keys 允许您代表实体调用 API。API 密钥不会过期,但是可以撤销 API 密钥。

API键具有相关联的权限。这意味着可以创建一个应用程序API密钥,该密钥可以用来读取有关终端设备的信息,但不能看到根密钥,也不能进行更改。

可以合并成员资格和API密钥,例如,您可以创建一个组织API密钥,该密钥具有列出组织成员所在的应用程序的权利,以及读取这些应用程序中终端设备信息的权利。

OAuth

Identity Server 是 OAuth 2.0 服务器。用户可以授权 OAuth 客户机访问他们的数据、管理授权,甚至管理单个访问令牌。

Join Server

连接服务器处理 LoRaWAN 连接流,包括网络和应用服务器身份验证和会话密钥生成。

Join Procedure

连接服务器通过 gRPC 接收来自网络服务器的加入请求,如果加入请求验证通过,则为注册设备发出加入接收。

如果接受了一个连接请求,Join Server将派生会话安全上下文,该上下文包含会话密钥,并由会话密钥 ID 标识。使用分别在网络服务器和应用服务器之间共享的密钥加密密钥(KEKs), Join Servers 加密派生的网络和应用程序会话密钥,并将会话密钥以加密的形式包含在 Join-accept 中。

Device Management

Join Servers 公开JsEndDeviceRegistry 服务用于终端设备管理。该服务的典型客户端有 Console 和 CLI。

Join Servers 存储设备根和会话密钥。

Session Key Retrieval

Join Servers 公开 rpc 以检索给定会话密钥ID的会话密钥。

Interoperability

Join Servers 公开了LoRaWAN后端接口 1.0 规范中定义的 AS-JS、vNS-JS 和 hNS-JS 服务。

Gateway Server

网关服务器维护与支持基站、UDP、MQTT 和 gRPC 协议的网关的连接。上行流量直接或间接转发给网络服务器,下行流量由网关调度。

Connective

网关可以通过多种协议连接到网关服务器。

  • Basic Station Protocol

网关可以通过基站 LNS 协议与网关服务器连接。建议使用此协议连接网关。

  • UDP Protocol

网关可以通过 UDP 协议连接到网关服务器。与每条消息一起发送的 EUI 用于标识网关。

如果在标识服务器中找到具有此 EUI 的网关,则消息与此网关相关。否则,根据网络配置,上行链路可能被路由或丢弃。但是,由于无法识别其区域参数,网络将不会向此网关发送下行链路。

旧版本的数据包转发器实现 UDP 协议没有实现任何排队系统下行链路,导致数据包丢失,因为 SX130x 集中器不缓冲多个下行链路。因此,对于 UDP 协议,Things Stack 实现了向下发送到网关的延迟,这意味着它们将由集中器发出。您可以每个网关单独禁用此功能,例如,如果网关和网关服务器之间的RTT过高。

  • MQTT Protocol

网关可以通过 MQTT 交换 Protocol Buffer 连接到网关服务器。MQTT 可在TLS上使用,提供网关和网络之间交换的消息的机密性。与使用 JSON 编码的 UDP 协议相比,使用 Protocol Buffer 的编码减少了带宽的使用。技术细节请参见网关服务器MQTT协议。

实现 MQTT 协议的包转发器(Packet forwarders)特定于Things Stack。

Gateway Information

当连接网关时,网关服务器会统计与网关交换的消息以及网关发送的状态消息。这些统计数据可以通过网关服务器的gRPC和HTTP api来检索。看到Gs服务。

Communication with Network Server

网关服务器的主要功能是维护与网关的连接,并作为网关和网络服务器之间的中继。

当网关服务器接收数据上行消息时,根据设备的 DevAddr 和配置的转发表决定发送到哪个 Network Server。连接请求被路由到所有已配置的端点。端点可以是集群的 gRPC 网络服务器,或者是中间流量路由机制。

网络服务器可以请求下行消息的传输。网关服务器尝试基于所选网关、发送消息的时间和 LoRaWAN 设置(下行链路类、RX1延迟和RX1/RX2数据速率和频率)来调度消息。

网关服务器跟踪所有发送的和连接到它的网关将要发送的下行链路,包括基于消息大小和数据速率的准确广播时间。这使得 The Things Stack 能够进行智能调度。除了定时和 LoRaWAN 设置,网关服务器考虑到适用的限制,包括:

  • 调度冲突:如果一个下行链路的发送与另一个下行链路的发送重叠,则下行链路将被拒绝。
  • 停飞时间:一些频带和频率计划有停飞时间限制,这意味着网关在发送下行链路后的一段时间内不能发射。
  • 频宽比:一些国家,如欧洲国家,有频宽比限制,禁止一个设备在一定范围内排放超过一定百分比的时间。
  • 停留时间:一些国家,如美国,受停留时间的规定,即传输的持续时间不能超过一定的限制。

Networking

Port Allocations

The following table lists the default ports used.

Purpose Protocol Authentication Port Port (TLS)
Gateway data Semtech Packet Forwarder None 1700 (UDP) N/A
Gateway data MQTT (V2) API key, token 1881 8881
Gateway data MQTT API key, token 1882 8882
Application data, events MQTT API key, token 1883 8883
Management, data, events gRPC API key, token 1884 8884
Management HTTP API key, token 1885 8885
Backend Interfaces HTTP Custom N/A 8886
LNS Web Sockets Auth Token, Custom 1887 8887
Tabs Hubs LNS Web Sockets Auth Token, Custom 1888 8888

Service Discovery

The Things Stack supports discovering services using DNS SRV records. This is useful when dialing a cluster only by host name; the supported services and target host name and port are discovered using DNS.

To support service discovery for your The Things Stack cluster, configure DNS SRV records with the following services and protocols:

Protocol SRV Service SRV Protocol SRV Target
gRPC ttn-v3-is-grpc tcp Identity Server
gRPC ttn-v3-gs-grpc tcp Gateway Server
Semtech Packet Forwarder ttn-v3-gs-udp udp Gateway Server
MQTT (V2) ttn-v3-gs-mqttv2 tcp Gateway Server
MQTT ttn-v3-gs-mqtt tcp Gateway Server
Basic Station LNS ttn-v3-gs-basicstationlns tcp Gateway Server
gRPC ttn-v3-ns-grpc tcp Network Server
gRPC ttn-v3-as-grpc tcp Application Server
MQTT ttn-v3-as-mqtt tcp Application Server
gRPC ttn-v3-js-grpc tcp Join Server
gRPC ttn-v3-dtc-grpc tcp Device Template Converter
gRPC ttn-v3-dcs-grpc tcp Device Claiming Server
gRPC ttn-v3-gcs-grpc tcp Gateway Configuration Server
gRPC ttn-v3-qrg-grpc tcp QR Code Generator