Compare commits

...

26 Commits

Author SHA1 Message Date
7b4f94375c Replace remaining _nb_k fields by _periodicity. 2025-06-06 11:37:44 +01:00
29674fc318 Fix mixing of Class-B _k vs _periodicity.
In the UI the k value (LoRaWAN < 1.0.4) was used as periodicity
(LoRaWAN 1.0.4). This renames the `_nb_k` fields to `_periodicity` to
align with the LoRaWAN 1.0.4 spec and updates the backend code to use
this value as periodicity as defined by the LoRaWAN 1.0.4 spec.

Fixes #670.
2025-06-05 12:13:49 +01:00
8804f774fb lrwn-filters: Update m_type > f_type. 2025-06-02 12:13:51 +01:00
3a0de8196f Rename m_type > f_type to align with LW 1.0.4 naming. 2025-06-02 12:02:32 +01:00
46bb01ccdc Sort NULL values as smallest value (devices and gateways last seen).
Fixes #683.
2025-05-26 14:50:26 +01:00
26cca09ce8 Fix custom root ca certificates not taken into account (#684) 2025-05-26 14:03:37 +01:00
c016cd1f7d Update dependencies. 2025-05-26 14:02:39 +01:00
1ead82e8a5 Bump golang.org/x/net from 0.36.0 to 0.38.0 in /api/go (#653)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.36.0 to 0.38.0.
- [Commits](https://github.com/golang/net/compare/v0.36.0...v0.38.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.38.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-26 13:51:30 +01:00
e8d001441c Bump version to 4.13.0-test.1 2025-05-23 09:36:26 +01:00
10e7907251 Generate API code. 2025-05-23 09:30:16 +01:00
39df55afb4 MeshCommand does not need a timestamp. 2025-05-23 09:14:57 +01:00
038e45e8f0 api: Rename Mesh to MeshEvent.
This is needed as we are also adding commands, thus we need MeshEvent
and MeshCommand messages.
2025-05-23 09:14:57 +01:00
5cf1120f20 Update gw proto & refactor Mesh Heartbeat event.
This refactors the gateway protobuf payloads, such that the
Concentratord can publish an Event message, containing one of the
possible events published by the Concentratord (uplink, stats or mesh
event). It also combines the possible Concentratord commands into a
single Command message. This simplifies the ZMQ interface as it is no
longer needed to match the payload type by string.

This also refactors the MeshHeartbeat message into a Mesh message, which
can contain multiple events, of which the Heartbeat is one of the
possible events.

The future goal is to make it possible to send different types of events
from the Gateway Mesh Relay gateways (e.g. battery status, ...) and to
make it possible to also send proprietary event types.
2025-05-23 09:14:57 +01:00
b8e14058f2 Geplace GETDEL by pipelined GET and DEL commands. (#682)
GETDEL was added in Redis 6.2, but is unfortunately not supported on all Azure Cache for Redis tiers.

Fixes #680.
2025-05-21 10:15:05 +01:00
10731c2be5 Make amqp integration exchange configurable (#677) 2025-05-21 09:45:19 +01:00
f1d46b1bc9 Update scheduler_run_after at device-session get.
This moves the setting of the scheduler_run_after to the function to get
the device-session based on provided PHYPayload. This way we reduce the
risk of overlapping Class-B / -C downlinks with a Class-A downlink, as
we update the scheduler_run_after during the "FOR UPDATE" transaction.
This also reduces one SQL query, as we combine it with the updating of
the device-session query (to update the uplink FCnt value).
2025-05-12 11:05:02 +01:00
c954cd3645 Store temp. mac-command state in device-session. 2025-05-09 14:27:25 +01:00
188ef3d8f3 Bump version to 4.12.1 2025-05-02 11:16:19 +01:00
0cff864f60 ui: Remove CodeEditor reloadKey.
With the migration from codemirror to ace, this workaround is no longer
needed to correctly render the UI component.
2025-05-02 11:09:59 +01:00
156f42ab82 Bump version to 4.12.1-test.1 2025-05-02 09:50:35 +01:00
c8b496d33f Update sqlite version in cross config. 2025-05-02 09:42:57 +01:00
8d2faf2d15 Update dependencies. 2025-05-02 09:42:24 +01:00
55d9ce0359 Bump vite from 6.2.6 to 6.2.7 in /ui (#668)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.2.6 to 6.2.7.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v6.2.7/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.2.7/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.2.7
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-02 08:52:27 +01:00
d002f5c97b ui: Format code. 2025-04-28 10:18:44 +01:00
9cf12a187c ui: Clear tenant id after delete.
Fixes #635.
2025-04-28 10:18:05 +01:00
1b5e5972f4 ui: Fix JSON enqueue issue / code-editor render issue.
This fixes two issues:

- An error logged to the console when enqueueing a JSON downlink payload
(Q.Va is not a function).
- The codemirror editor has been replaced by ace, to solve a potential
rendering issue within ReactJS / Antd.

Closes #658.
2025-04-28 10:09:52 +01:00
113 changed files with 3217 additions and 2055 deletions

View File

@ -28,7 +28,7 @@ jobs:
name: Install Nix
uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-24.11
nix_path: nixpkgs=channel:nixos-25.05
-
name: Cargo cache
uses: actions/cache@v4
@ -69,7 +69,7 @@ jobs:
name: Install Nix
uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-24.11
nix_path: nixpkgs=channel:nixos-25.05
-
name: Cargo cache
uses: actions/cache@v4

710
Cargo.lock generated

File diff suppressed because it is too large Load Diff

6
api/go/go.mod vendored
View File

@ -11,8 +11,8 @@ require (
require (
github.com/golang/protobuf v1.5.4 // indirect
golang.org/x/net v0.36.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.23.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa // indirect
)

12
api/go/go.sum vendored
View File

@ -2,12 +2,12 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa h1:Jt1XW5PaLXF1/ePZrznsh/aAUvI7Adfc3LY1dAKlzRs=
google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa/go.mod h1:K4kfzHtI0kqWA79gecJarFtDn/Mls+GxQcg3Zox91Ac=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa h1:RBgMaUMP+6soRkik4VoN8ojR2nex2TqZwjSSogic+eo=

2532
api/go/gw/gw.pb.go vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,16 @@
{
"name": "@chirpstack/chirpstack-api-grpc-web",
"version": "4.12.0",
"version": "4.13.0-test.1",
"description": "Chirpstack gRPC-web API",
"license": "MIT",
"devDependencies": {
"grpc-tools": "^1.12.4",
"grpc-tools": "^1.13.0",
"ts-protoc-gen": "^0.15.0",
"typescript": "^5.1.6"
"typescript": "^5.8.3"
},
"dependencies": {
"@types/google-protobuf": "^3.15.12",
"google-protobuf": "^3.21.2",
"google-protobuf": "^3.21.4",
"grpc-web": "^1.5.0"
}
}

View File

@ -146,15 +146,20 @@ glob@^7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
google-protobuf@^3.15.5, google-protobuf@^3.21.2:
google-protobuf@^3.15.5:
version "3.21.2"
resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.21.2.tgz#4580a2bea8bbb291ee579d1fefb14d6fa3070ea4"
integrity sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==
grpc-tools@^1.12.4:
version "1.12.4"
resolved "https://registry.yarnpkg.com/grpc-tools/-/grpc-tools-1.12.4.tgz#a044c9e8157941033ea7a5f144c2dc9dc4501de4"
integrity sha512-5+mLAJJma3BjnW/KQp6JBjUMgvu7Mu3dBvBPd1dcbNIb+qiR0817zDpgPjS7gRb+l/8EVNIa3cB02xI9JLToKg==
google-protobuf@^3.21.4:
version "3.21.4"
resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.21.4.tgz#2f933e8b6e5e9f8edde66b7be0024b68f77da6c9"
integrity sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==
grpc-tools@^1.13.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/grpc-tools/-/grpc-tools-1.13.0.tgz#a4fea8eebce51fb9fec00055a3e52016dfd5af89"
integrity sha512-7CbkJ1yWPfX0nHjbYG58BQThNhbICXBZynzCUxCb3LzX5X9B3hQbRY2STiRgIEiLILlK9fgl0z0QVGwPCdXf5g==
dependencies:
"@mapbox/node-pre-gyp" "^1.0.5"
@ -376,10 +381,10 @@ ts-protoc-gen@^0.15.0:
dependencies:
google-protobuf "^3.15.5"
typescript@^5.1.6:
version "5.4.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.3.tgz#5c6fedd4c87bee01cd7a528a30145521f8e0feff"
integrity sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==
typescript@^5.8.3:
version "5.8.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e"
integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==
util-deprecate@^1.0.1:
version "1.0.2"

View File

@ -8,7 +8,7 @@ plugins {
}
group = "io.chirpstack"
version = "4.12.0"
version = "4.13.0-test.1"
repositories {
mavenCentral()

12
api/js/package.json vendored
View File

@ -1,17 +1,17 @@
{
"name": "@chirpstack/chirpstack-api",
"version": "4.12.0",
"version": "4.13.0-test.1",
"description": "Chirpstack JS and TS API",
"license": "MIT",
"devDependencies": {
"grpc-tools": "^1.12.4",
"grpc-tools": "^1.13.0",
"ts-protoc-gen": "^0.15.0",
"typescript": "^5.1.6"
"typescript": "^5.8.3"
},
"dependencies": {
"@grpc/grpc-js": "^1.10.4",
"@grpc/grpc-js": "^1.13.3",
"@mapbox/node-pre-gyp": "^1.0.11",
"@types/google-protobuf": "^3.15.6",
"google-protobuf": "^3.21.2"
"@types/google-protobuf": "^3.15.12",
"google-protobuf": "^3.21.4"
}
}

39
api/js/yarn.lock vendored
View File

@ -2,10 +2,10 @@
# yarn lockfile v1
"@grpc/grpc-js@^1.10.4":
version "1.10.9"
resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.10.9.tgz#468cc1549a3fe37b760a16745fb7685d91f4f10c"
integrity sha512-5tcgUctCG0qoNyfChZifz2tJqbRbXVO9J7X6duFcOjY3HUNCxg5D0ZCK7EP9vIcZ0zRpLU9bWkyCqVCLZ46IbQ==
"@grpc/grpc-js@^1.13.3":
version "1.13.3"
resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.13.3.tgz#6ad08d186c2a8651697085f790c5c68eaca45904"
integrity sha512-FTXHdOoPbZrBjlVLHuKbDZnsTxXv2BlHF57xw6LuThXacXvtkahEPED0CKMk6obZDf65Hv4k3z62eyPNpvinIg==
dependencies:
"@grpc/proto-loader" "^0.7.13"
"@js-sdsl/ordered-map" "^4.4.2"
@ -93,10 +93,10 @@
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
"@types/google-protobuf@^3.15.6":
version "3.15.6"
resolved "https://registry.yarnpkg.com/@types/google-protobuf/-/google-protobuf-3.15.6.tgz#674a69493ef2c849b95eafe69167ea59079eb504"
integrity sha512-pYVNNJ+winC4aek+lZp93sIKxnXt5qMkuKmaqS3WGuTq0Bw1ZDYNBgzG5kkdtwcv+GmYJGo3yEg6z2cKKAiEdw==
"@types/google-protobuf@^3.15.12":
version "3.15.12"
resolved "https://registry.yarnpkg.com/@types/google-protobuf/-/google-protobuf-3.15.12.tgz#eb2ba0eddd65712211a2b455dc6071d665ccf49b"
integrity sha512-40um9QqwHjRS92qnOaDpL7RmDK15NuZYo9HihiJRbYkMQZlWnuH8AdvbMy8/o6lgLmKbDUKa+OALCltHdbOTpQ==
"@types/node@>=13.7.0":
version "20.4.8"
@ -265,15 +265,20 @@ glob@^7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
google-protobuf@^3.15.5, google-protobuf@^3.21.2:
google-protobuf@^3.15.5:
version "3.21.2"
resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.21.2.tgz#4580a2bea8bbb291ee579d1fefb14d6fa3070ea4"
integrity sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==
grpc-tools@^1.12.4:
version "1.12.4"
resolved "https://registry.yarnpkg.com/grpc-tools/-/grpc-tools-1.12.4.tgz#a044c9e8157941033ea7a5f144c2dc9dc4501de4"
integrity sha512-5+mLAJJma3BjnW/KQp6JBjUMgvu7Mu3dBvBPd1dcbNIb+qiR0817zDpgPjS7gRb+l/8EVNIa3cB02xI9JLToKg==
google-protobuf@^3.21.4:
version "3.21.4"
resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.21.4.tgz#2f933e8b6e5e9f8edde66b7be0024b68f77da6c9"
integrity sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==
grpc-tools@^1.13.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/grpc-tools/-/grpc-tools-1.13.0.tgz#a4fea8eebce51fb9fec00055a3e52016dfd5af89"
integrity sha512-7CbkJ1yWPfX0nHjbYG58BQThNhbICXBZynzCUxCb3LzX5X9B3hQbRY2STiRgIEiLILlK9fgl0z0QVGwPCdXf5g==
dependencies:
"@mapbox/node-pre-gyp" "^1.0.5"
@ -523,10 +528,10 @@ ts-protoc-gen@^0.15.0:
dependencies:
google-protobuf "^3.15.5"
typescript@^5.1.6:
version "5.1.6"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274"
integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==
typescript@^5.8.3:
version "5.8.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e"
integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==
util-deprecate@^1.0.1:
version "1.0.2"

View File

@ -9,7 +9,7 @@ plugins {
}
group = "io.chirpstack"
version = "4.12.0"
version = "4.13.0-test.1"
repositories {
mavenCentral()

View File

@ -3,7 +3,7 @@
"description": "Chirpstack PHP API",
"license": "MIT",
"type": "library",
"version": "4.12.0",
"version": "4.13.0-test.1",
"require": {
"php": ">=7.0.0",
"grpc/grpc": "^v1.57.0",

View File

@ -240,11 +240,15 @@ message DeviceProfile {
// from the device (if requested).
uint32 class_b_timeout = 16;
// Class-B ping-slots per beacon period.
// Class-B ping-slot periodicity.
// Valid options are: 0 - 7.
//
// The actual number of ping-slots per beacon period equals to 2^k.
uint32 class_b_ping_slot_nb_k = 17;
// Number of ping-slots per beacon-period:
// pingNb = 2^(7-periodicity)
//
// Periodicity: 0 = 128 ping-slots per beacon period = ~ every 1 sec
// Periodicity: 7 = 1 ping-slot per beacon period = ~ every 128 sec
uint32 class_b_ping_slot_periodicity = 17;
// Class-B ping-slot DR.
uint32 class_b_ping_slot_dr = 18;

View File

@ -117,11 +117,15 @@ message DeviceProfileTemplate {
// This is the maximum time ChirpStack will wait to receive an acknowledgement from the device (if requested).
uint32 class_b_timeout = 18;
// Class-B ping-slots per beacon period.
// Class-B ping-slot periodicity (only for Class-B).
// Valid options are: 0 - 7.
//
// The actual number of ping-slots per beacon period equals to 2^k.
uint32 class_b_ping_slot_nb_k = 19;
// Number of ping-slots per beacon-period:
// pingNb = 2^(7-periodicity)
//
// Periodicity: 0 = 128 ping-slots per beacon period = ~ every 1 sec
// Periodicity: 7 = 1 ping-slot per beacon period = ~ every 128 sec
uint32 class_b_ping_slot_periodicity = 19;
// Class-B ping-slot DR.
uint32 class_b_ping_slot_dr = 20;

View File

@ -104,7 +104,14 @@ message FuotaDeployment {
uint32 multicast_dr = 7;
// Multicast ping-slot period (Class-B only).
uint32 multicast_class_b_ping_slot_nb_k = 8;
// Valid options are: 0 - 7.
//
// Number of ping-slots per beacon-period:
// pingNb = 2^(7-periodicity)
//
// Periodicity: 0 = 128 ping-slots per beacon period = ~ every 1 sec
// Periodicity: 7 = 1 ping-slot per beacon period = ~ every 128 sec
uint32 multicast_class_b_ping_slot_periodicity = 8;
// Multicast frequency (Hz).
uint32 multicast_frequency = 9;

View File

@ -165,15 +165,15 @@ message MulticastGroup {
// Frequency (Hz).
uint32 frequency = 11;
// Ping-slot period (only for Class-B).
// Deprecated: use class_b_ping_slot_nb_k.
uint32 class_b_ping_slot_period = 12;
// Class-B ping-slots per beacon period (only for Class-B).
// Valid options are: 0 - 7;
// Class-B ping-slot periodicity (only for Class-B).
// Valid options are: 0 - 7.
//
// The actual number of ping-slots per beacon period equals to 2^k.
uint32 class_b_ping_slot_nb_k = 14;
// Number of ping-slots per beacon-period:
// pingNb = 2^(7-periodicity)
//
// Periodicity: 0 = 128 ping-slots per beacon period = ~ every 1 sec
// Periodicity: 7 = 1 ping-slot per beacon period = ~ every 128 sec
uint32 class_b_ping_slot_periodicity = 14;
// Scheduling type (only for Class-C).
MulticastGroupSchedulingType class_c_scheduling_type = 13;

View File

@ -67,7 +67,7 @@ enum Region {
ISM2400 = 11;
}
enum MType {
enum FType {
// JoinRequest.
JOIN_REQUEST = 0;

125
api/proto/gw/gw.proto vendored
View File

@ -104,6 +104,82 @@ enum TxAckStatus {
DUTY_CYCLE_OVERFLOW = 11;
}
// Gateway events as reported by the ChirpStack Concentratord ZMQ interface.
message Event {
oneof event {
// Uplink frame.
UplinkFrame uplink_frame = 1;
// Gateway stats.
GatewayStats gateway_stats = 2;
// Gateway Mesh Event.
MeshEvent mesh = 3;
}
}
// Commands that can be sent to the ChirpStack Concentratord ZMQ interface.
message Command {
oneof command {
// Downlink frame.
DownlinkFrame send_downlink_frame = 1;
// Gateway configuration.
GatewayConfiguration set_gateway_configuration = 2;
// Get Gateway ID.
GetGatewayIdRequest get_gateway_id = 3;
// Get location.
GetLocationRequest get_location = 4;
// Gateway Mesh Command.
MeshCommand mesh = 5;
}
}
message MeshEvent {
// Gateway ID (of the Border Gateway).
string gateway_id = 1;
// Relay ID.
string relay_id = 2;
// Timestamp (second precision).
google.protobuf.Timestamp time = 3;
// Mesh events.
repeated MeshEventItem events = 4;
}
message MeshEventItem {
oneof event {
// Proprietary Mesh event.
MeshEventProprietary proprietary = 1;
// Mesh heartbeat.
MeshEventHeartbeat heartbeat = 2;
}
}
message MeshCommand {
// Gateway ID (of the Border Gateway).
string gateway_id = 1;
// Relay ID.
string relay_id = 2;
// Mesh events.
repeated MeshCommandItem commands = 3;
}
message MeshCommandItem {
oneof command {
// Proprietary Mesh command.
MeshCommandProprietary proprietary = 1;
}
}
message Modulation {
oneof parameters {
// LoRa modulation information.
@ -611,6 +687,23 @@ message GatewayConfiguration {
google.protobuf.Duration stats_interval = 4;
}
message GetGatewayIdRequest {}
message GetGatewayIdResponse {
// Gateway ID.
string gateway_id = 1;
}
message GetLocationRequest {}
message GetLocationResponse {
// Location.
common.Location location = 1;
// Last updated at.
google.protobuf.Timestamp updated_at = 2;
}
message ChannelConfiguration {
// Frequency (Hz).
uint32 frequency = 1;
@ -751,21 +844,13 @@ message ConnState {
}
// Gateway Mesh heartbeat (sent periodically by the Relay Gateways).
message MeshHeartbeat {
// Gateway ID (of the Border Gateway).
string gateway_id = 1;
// Relay ID.
string relay_id = 2;
// Timestamp (second precision).
google.protobuf.Timestamp time = 3;
message MeshEventHeartbeat {
// Relay path.
repeated MeshHeartbeatRelayPath relay_path = 4;
repeated MeshEventHeartbeatRelayPath relay_path = 4;
}
message MeshHeartbeatRelayPath {
message MeshEventHeartbeatRelayPath {
// Relay ID.
string relay_id = 1;
@ -775,3 +860,21 @@ message MeshHeartbeatRelayPath {
// SNR.
int32 snr = 3;
}
// Proprietary mesh event.
message MeshEventProprietary {
// Event type.
uint32 event_type = 1;
// Payload.
bytes payload = 2;
}
// Proprietary mesh command.
message MeshCommandProprietary {
// Command type.
uint32 command_type = 1;
// Payload.
bytes payload = 2;
}

View File

@ -142,6 +142,9 @@ message DeviceSession {
// Relay state.
Relay relay = 41;
// Pending mac-commands.
map<uint32, bytes> mac_command_pending = 43;
}
message UplinkAdrHistory {

View File

@ -24,8 +24,8 @@ message UplinkFrameLog {
// RX meta-data.
repeated gw.UplinkRxInfo rx_info = 3;
// Message type.
common.MType m_type = 4;
// Frame type.
common.FType f_type = 4;
// Device address (optional).
string dev_addr = 5;
@ -59,8 +59,8 @@ message DownlinkFrameLog {
// Gateway ID (EUI64).
string gateway_id = 5;
// Message type.
common.MType m_type = 6;
// Frame type.
common.FType f_type = 6;
// Device address (optional).
string dev_addr = 7;

View File

@ -32,8 +32,8 @@ message UplinkMeta {
// Application payload byte count.
uint32 application_payload_byte_count = 6;
// Message type.
common.MType message_type = 7;
// Frame type.
common.FType frame_type = 7;
}
message DownlinkMeta {
@ -55,8 +55,8 @@ message DownlinkMeta {
// Application payload byte count.
uint32 application_payload_byte_count = 6;
// Message type.
common.MType message_type = 7;
// Frame type.
common.FType frame_type = 7;
// Gateway ID (EUI64).
string gateway_id = 8;

View File

@ -18,7 +18,7 @@ CLASSIFIERS = [
setup(
name='chirpstack-api',
version = "4.12.0",
version = "4.13.0-test.1",
url='https://github.com/brocaar/chirpstack-api',
author='Orne Brocaar',
author_email='info@brocaar.com',

2
api/rust/Cargo.toml vendored
View File

@ -1,7 +1,7 @@
[package]
name = "chirpstack_api"
description = "ChirpStack Protobuf / gRPC API definitions."
version = "4.12.0"
version = "4.13.0-test.1"
authors = ["Orne Brocaar <info@brocaar.com>"]
license = "MIT"
homepage = "https://www.chirpstack.io"

View File

@ -240,11 +240,15 @@ message DeviceProfile {
// from the device (if requested).
uint32 class_b_timeout = 16;
// Class-B ping-slots per beacon period.
// Class-B ping-slot periodicity.
// Valid options are: 0 - 7.
//
// The actual number of ping-slots per beacon period equals to 2^k.
uint32 class_b_ping_slot_nb_k = 17;
// Number of ping-slots per beacon-period:
// pingNb = 2^(7-periodicity)
//
// Periodicity: 0 = 128 ping-slots per beacon period = ~ every 1 sec
// Periodicity: 7 = 1 ping-slot per beacon period = ~ every 128 sec
uint32 class_b_ping_slot_periodicity = 17;
// Class-B ping-slot DR.
uint32 class_b_ping_slot_dr = 18;

View File

@ -117,11 +117,15 @@ message DeviceProfileTemplate {
// This is the maximum time ChirpStack will wait to receive an acknowledgement from the device (if requested).
uint32 class_b_timeout = 18;
// Class-B ping-slots per beacon period.
// Class-B ping-slot periodicity (only for Class-B).
// Valid options are: 0 - 7.
//
// The actual number of ping-slots per beacon period equals to 2^k.
uint32 class_b_ping_slot_nb_k = 19;
// Number of ping-slots per beacon-period:
// pingNb = 2^(7-periodicity)
//
// Periodicity: 0 = 128 ping-slots per beacon period = ~ every 1 sec
// Periodicity: 7 = 1 ping-slot per beacon period = ~ every 128 sec
uint32 class_b_ping_slot_periodicity = 19;
// Class-B ping-slot DR.
uint32 class_b_ping_slot_dr = 20;

View File

@ -104,7 +104,14 @@ message FuotaDeployment {
uint32 multicast_dr = 7;
// Multicast ping-slot period (Class-B only).
uint32 multicast_class_b_ping_slot_nb_k = 8;
// Valid options are: 0 - 7.
//
// Number of ping-slots per beacon-period:
// pingNb = 2^(7-periodicity)
//
// Periodicity: 0 = 128 ping-slots per beacon period = ~ every 1 sec
// Periodicity: 7 = 1 ping-slot per beacon period = ~ every 128 sec
uint32 multicast_class_b_ping_slot_periodicity = 8;
// Multicast frequency (Hz).
uint32 multicast_frequency = 9;

View File

@ -165,15 +165,15 @@ message MulticastGroup {
// Frequency (Hz).
uint32 frequency = 11;
// Ping-slot period (only for Class-B).
// Deprecated: use class_b_ping_slot_nb_k.
uint32 class_b_ping_slot_period = 12;
// Class-B ping-slots per beacon period (only for Class-B).
// Valid options are: 0 - 7;
// Class-B ping-slot periodicity (only for Class-B).
// Valid options are: 0 - 7.
//
// The actual number of ping-slots per beacon period equals to 2^k.
uint32 class_b_ping_slot_nb_k = 14;
// Number of ping-slots per beacon-period:
// pingNb = 2^(7-periodicity)
//
// Periodicity: 0 = 128 ping-slots per beacon period = ~ every 1 sec
// Periodicity: 7 = 1 ping-slot per beacon period = ~ every 128 sec
uint32 class_b_ping_slot_periodicity = 14;
// Scheduling type (only for Class-C).
MulticastGroupSchedulingType class_c_scheduling_type = 13;

View File

@ -67,7 +67,7 @@ enum Region {
ISM2400 = 11;
}
enum MType {
enum FType {
// JoinRequest.
JOIN_REQUEST = 0;

View File

@ -104,6 +104,82 @@ enum TxAckStatus {
DUTY_CYCLE_OVERFLOW = 11;
}
// Gateway events as reported by the ChirpStack Concentratord ZMQ interface.
message Event {
oneof event {
// Uplink frame.
UplinkFrame uplink_frame = 1;
// Gateway stats.
GatewayStats gateway_stats = 2;
// Gateway Mesh Event.
MeshEvent mesh = 3;
}
}
// Commands that can be sent to the ChirpStack Concentratord ZMQ interface.
message Command {
oneof command {
// Downlink frame.
DownlinkFrame send_downlink_frame = 1;
// Gateway configuration.
GatewayConfiguration set_gateway_configuration = 2;
// Get Gateway ID.
GetGatewayIdRequest get_gateway_id = 3;
// Get location.
GetLocationRequest get_location = 4;
// Gateway Mesh Command.
MeshCommand mesh = 5;
}
}
message MeshEvent {
// Gateway ID (of the Border Gateway).
string gateway_id = 1;
// Relay ID.
string relay_id = 2;
// Timestamp (second precision).
google.protobuf.Timestamp time = 3;
// Mesh events.
repeated MeshEventItem events = 4;
}
message MeshEventItem {
oneof event {
// Proprietary Mesh event.
MeshEventProprietary proprietary = 1;
// Mesh heartbeat.
MeshEventHeartbeat heartbeat = 2;
}
}
message MeshCommand {
// Gateway ID (of the Border Gateway).
string gateway_id = 1;
// Relay ID.
string relay_id = 2;
// Mesh events.
repeated MeshCommandItem commands = 3;
}
message MeshCommandItem {
oneof command {
// Proprietary Mesh command.
MeshCommandProprietary proprietary = 1;
}
}
message Modulation {
oneof parameters {
// LoRa modulation information.
@ -611,6 +687,23 @@ message GatewayConfiguration {
google.protobuf.Duration stats_interval = 4;
}
message GetGatewayIdRequest {}
message GetGatewayIdResponse {
// Gateway ID.
string gateway_id = 1;
}
message GetLocationRequest {}
message GetLocationResponse {
// Location.
common.Location location = 1;
// Last updated at.
google.protobuf.Timestamp updated_at = 2;
}
message ChannelConfiguration {
// Frequency (Hz).
uint32 frequency = 1;
@ -751,21 +844,13 @@ message ConnState {
}
// Gateway Mesh heartbeat (sent periodically by the Relay Gateways).
message MeshHeartbeat {
// Gateway ID (of the Border Gateway).
string gateway_id = 1;
// Relay ID.
string relay_id = 2;
// Timestamp (second precision).
google.protobuf.Timestamp time = 3;
message MeshEventHeartbeat {
// Relay path.
repeated MeshHeartbeatRelayPath relay_path = 4;
repeated MeshEventHeartbeatRelayPath relay_path = 4;
}
message MeshHeartbeatRelayPath {
message MeshEventHeartbeatRelayPath {
// Relay ID.
string relay_id = 1;
@ -775,3 +860,21 @@ message MeshHeartbeatRelayPath {
// SNR.
int32 snr = 3;
}
// Proprietary mesh event.
message MeshEventProprietary {
// Event type.
uint32 event_type = 1;
// Payload.
bytes payload = 2;
}
// Proprietary mesh command.
message MeshCommandProprietary {
// Command type.
uint32 command_type = 1;
// Payload.
bytes payload = 2;
}

View File

@ -142,6 +142,9 @@ message DeviceSession {
// Relay state.
Relay relay = 41;
// Pending mac-commands.
map<uint32, bytes> mac_command_pending = 43;
}
message UplinkAdrHistory {

View File

@ -24,8 +24,8 @@ message UplinkFrameLog {
// RX meta-data.
repeated gw.UplinkRxInfo rx_info = 3;
// Message type.
common.MType m_type = 4;
// Frame type.
common.FType f_type = 4;
// Device address (optional).
string dev_addr = 5;
@ -59,8 +59,8 @@ message DownlinkFrameLog {
// Gateway ID (EUI64).
string gateway_id = 5;
// Message type.
common.MType m_type = 6;
// Frame type.
common.FType f_type = 6;
// Device address (optional).
string dev_addr = 7;

View File

@ -32,8 +32,8 @@ message UplinkMeta {
// Application payload byte count.
uint32 application_payload_byte_count = 6;
// Message type.
common.MType message_type = 7;
// Frame type.
common.FType frame_type = 7;
}
message DownlinkMeta {
@ -55,8 +55,8 @@ message DownlinkMeta {
// Application payload byte count.
uint32 application_payload_byte_count = 6;
// Message type.
common.MType message_type = 7;
// Frame type.
common.FType frame_type = 7;
// Gateway ID (EUI64).
string gateway_id = 8;

View File

@ -7,17 +7,17 @@ include!(concat!(env!("OUT_DIR"), "/common/common.rs"));
include!(concat!(env!("OUT_DIR"), "/common/common.serde.rs"));
#[allow(clippy::from_over_into)]
impl Into<String> for MType {
impl Into<String> for FType {
fn into(self) -> String {
match self {
MType::JoinRequest => "JoinRequest",
MType::JoinAccept => "JoinAccept",
MType::UnconfirmedDataUp => "UnconfirmedDataUp",
MType::UnconfirmedDataDown => "UnconfirmedDataDown",
MType::ConfirmedDataUp => "ConfirmedDataUp",
MType::ConfirmedDataDown => "ConfirmedDataDown",
MType::RejoinRequest => "RejoinRequest",
MType::Proprietary => "Proprietary",
FType::JoinRequest => "JoinRequest",
FType::JoinAccept => "JoinAccept",
FType::UnconfirmedDataUp => "UnconfirmedDataUp",
FType::UnconfirmedDataDown => "UnconfirmedDataDown",
FType::ConfirmedDataUp => "ConfirmedDataUp",
FType::ConfirmedDataDown => "ConfirmedDataDown",
FType::RejoinRequest => "RejoinRequest",
FType::Proprietary => "Proprietary",
}
.to_string()
}

9
api/rust/src/lib.rs vendored
View File

@ -1,14 +1,17 @@
pub use prost;
pub use prost_types;
#[cfg(feature = "json")]
pub use pbjson_types;
pub use prost;
#[cfg(feature = "api")]
pub use tonic;
#[cfg(feature = "api")]
pub mod api;
#[cfg(feature = "internal")]
pub mod internal;
pub mod common;
pub mod gw;
pub mod integration;
#[cfg(feature = "internal")]
pub mod internal;
pub mod stream;

View File

@ -1,6 +1,6 @@
[package]
name = "backend"
version = "4.12.0"
version = "4.13.0-test.1"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2018"
publish = false

View File

@ -3,14 +3,14 @@
description = "Library for building external ChirpStack integrations"
homepage = "https://www.chirpstack.io/"
license = "MIT"
version = "4.12.0"
version = "4.13.0-test.1"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
repository = "https://github.com/chirpstack/chirpstack"
[dependencies]
chirpstack_api = { path = "../api/rust", version = "4.12.0" }
redis = { version = "0.29", features = [
chirpstack_api = { path = "../api/rust", version = "4.13.0-test.1" }
redis = { version = "0.31", features = [
"cluster-async",
"tokio-rustls-comp",
] }

View File

@ -3,7 +3,7 @@
description = "ChirpStack is an open-source LoRaWAN(TM) Network Server"
repository = "https://github.com/chirpstack/chirpstack"
homepage = "https://www.chirpstack.io/"
version = "4.12.0"
version = "4.13.0-test.1"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
publish = false
@ -34,8 +34,8 @@
tokio-postgres = { version = "0.7", optional = true }
tokio-postgres-rustls = { version = "0.13", optional = true }
bigdecimal = "0.4"
redis = { version = "0.29", features = ["tls-rustls", "tokio-rustls-comp"] }
deadpool-redis = { version = "0.20", features = ["cluster", "serde"] }
redis = { version = "0.31", features = ["tls-rustls", "tokio-rustls-comp"] }
deadpool-redis = { version = "0.21", features = ["cluster", "serde"] }
# Logging
tracing = "0.1"
@ -137,7 +137,7 @@
] }
# Misc
uuid = { version = "1.16", features = ["v4", "serde"] }
uuid = { version = "1.17", features = ["v4", "serde"] }
chrono = "0.4"
async-trait = "0.1"
aes = "0.8"
@ -145,7 +145,7 @@
base64 = "0.22"
async-recursion = "1.1"
regex = "1.11"
petgraph = "0.7"
petgraph = "0.8"
prometheus-client = "0.23"
pin-project = "1.1"
scoped-futures = { version = "0.1", features = ["std"] }

View File

@ -0,0 +1,8 @@
alter table fuota_deployment
rename column multicast_class_b_ping_slot_periodicity to multicast_class_b_ping_slot_nb_k;
alter table multicast_group
rename column class_b_ping_slot_periodicity to class_b_ping_slot_nb_k;
alter table device_profile_template
rename column class_b_ping_slot_periodicity to class_b_ping_slot_nb_k;

View File

@ -0,0 +1,8 @@
alter table device_profile_template
rename column class_b_ping_slot_nb_k to class_b_ping_slot_periodicity;
alter table multicast_group
rename column class_b_ping_slot_nb_k to class_b_ping_slot_periodicity;
alter table fuota_deployment
rename column multicast_class_b_ping_slot_nb_k to multicast_class_b_ping_slot_periodicity;

View File

@ -0,0 +1,8 @@
alter table fuota_deployment
rename column multicast_class_b_ping_slot_periodicity to multicast_class_b_ping_slot_nb_k;
alter table multicast_group
rename column class_b_ping_slot_periodicity to class_b_ping_slot_nb_k;
alter table device_profile_template
rename column class_b_ping_slot_periodicity to class_b_ping_slot_nb_k;

View File

@ -0,0 +1,8 @@
alter table device_profile_template
rename column class_b_ping_slot_nb_k to class_b_ping_slot_periodicity;
alter table multicast_group
rename column class_b_ping_slot_nb_k to class_b_ping_slot_periodicity;
alter table fuota_deployment
rename column multicast_class_b_ping_slot_nb_k to multicast_class_b_ping_slot_periodicity;

View File

@ -252,7 +252,7 @@ async fn _handle_pr_start_req(b: &[u8]) -> Result<backend::PRStartAnsPayload> {
let pl: backend::PRStartReqPayload = serde_json::from_slice(b)?;
let phy = lrwn::PhyPayload::from_slice(&pl.phy_payload)?;
if phy.mhdr.m_type == lrwn::MType::JoinRequest {
if phy.mhdr.f_type == lrwn::FType::JoinRequest {
_handle_pr_start_req_join(pl, phy).await
} else {
_handle_pr_start_req_data(pl, phy).await

View File

@ -94,7 +94,7 @@ impl DeviceProfileService for DeviceProfile {
class_b_params: if req_dp.supports_class_b {
Some(fields::ClassBParams {
timeout: req_dp.class_b_timeout as u16,
ping_slot_nb_k: req_dp.class_b_ping_slot_nb_k as u8,
ping_slot_periodicity: req_dp.class_b_ping_slot_periodicity as u8,
ping_slot_dr: req_dp.class_b_ping_slot_dr as u8,
ping_slot_freq: req_dp.class_b_ping_slot_freq,
})
@ -205,7 +205,7 @@ impl DeviceProfileService for DeviceProfile {
supports_class_b: dp.supports_class_b,
supports_class_c: dp.supports_class_c,
class_b_timeout: class_b_params.timeout as u32,
class_b_ping_slot_nb_k: class_b_params.ping_slot_nb_k as u32,
class_b_ping_slot_periodicity: class_b_params.ping_slot_periodicity as u32,
class_b_ping_slot_dr: class_b_params.ping_slot_dr as u32,
class_b_ping_slot_freq: class_b_params.ping_slot_freq as u32,
class_c_timeout: class_c_params.timeout as u32,
@ -350,7 +350,7 @@ impl DeviceProfileService for DeviceProfile {
class_b_params: if req_dp.supports_class_b {
Some(fields::ClassBParams {
timeout: req_dp.class_b_timeout as u16,
ping_slot_nb_k: req_dp.class_b_ping_slot_nb_k as u8,
ping_slot_periodicity: req_dp.class_b_ping_slot_periodicity as u8,
ping_slot_dr: req_dp.class_b_ping_slot_dr as u8,
ping_slot_freq: req_dp.class_b_ping_slot_freq,
})

View File

@ -60,7 +60,7 @@ impl DeviceProfileTemplateService for DeviceProfileTemplate {
supports_class_b: req_dp.supports_class_b,
supports_class_c: req_dp.supports_class_c,
class_b_timeout: req_dp.class_b_timeout as i32,
class_b_ping_slot_nb_k: req_dp.class_b_ping_slot_nb_k as i32,
class_b_ping_slot_periodicity: req_dp.class_b_ping_slot_periodicity as i32,
class_b_ping_slot_dr: req_dp.class_b_ping_slot_dr as i16,
class_b_ping_slot_freq: req_dp.class_b_ping_slot_freq as i64,
class_c_timeout: req_dp.class_c_timeout as i32,
@ -132,7 +132,7 @@ impl DeviceProfileTemplateService for DeviceProfileTemplate {
supports_class_b: dp.supports_class_b,
supports_class_c: dp.supports_class_c,
class_b_timeout: dp.class_b_timeout as u32,
class_b_ping_slot_nb_k: dp.class_b_ping_slot_nb_k as u32,
class_b_ping_slot_periodicity: dp.class_b_ping_slot_periodicity as u32,
class_b_ping_slot_dr: dp.class_b_ping_slot_dr as u32,
class_b_ping_slot_freq: dp.class_b_ping_slot_freq as u32,
class_c_timeout: dp.class_c_timeout as u32,
@ -201,7 +201,7 @@ impl DeviceProfileTemplateService for DeviceProfileTemplate {
supports_class_b: req_dp.supports_class_b,
supports_class_c: req_dp.supports_class_c,
class_b_timeout: req_dp.class_b_timeout as i32,
class_b_ping_slot_nb_k: req_dp.class_b_ping_slot_nb_k as i32,
class_b_ping_slot_periodicity: req_dp.class_b_ping_slot_periodicity as i32,
class_b_ping_slot_dr: req_dp.class_b_ping_slot_dr as i16,
class_b_ping_slot_freq: req_dp.class_b_ping_slot_freq as i64,
class_c_timeout: req_dp.class_c_timeout as i32,

View File

@ -63,7 +63,8 @@ impl FuotaService for Fuota {
.multicast_class_c_scheduling_type()
.from_proto(),
multicast_dr: req_dp.multicast_dr as i16,
multicast_class_b_ping_slot_nb_k: req_dp.multicast_class_b_ping_slot_nb_k as i16,
multicast_class_b_ping_slot_periodicity: req_dp.multicast_class_b_ping_slot_periodicity
as i16,
multicast_frequency: req_dp.multicast_frequency as i64,
multicast_timeout: req_dp.multicast_timeout as i16,
unicast_max_retry_count: req_dp.unicast_max_retry_count as i16,
@ -138,7 +139,8 @@ impl FuotaService for Fuota {
.to_proto()
.into(),
multicast_dr: dp.multicast_dr as u32,
multicast_class_b_ping_slot_nb_k: dp.multicast_class_b_ping_slot_nb_k as u32,
multicast_class_b_ping_slot_periodicity: dp.multicast_class_b_ping_slot_periodicity
as u32,
multicast_frequency: dp.multicast_frequency as u32,
multicast_timeout: dp.multicast_timeout as u32,
unicast_max_retry_count: dp.unicast_max_retry_count as u32,
@ -217,7 +219,8 @@ impl FuotaService for Fuota {
.multicast_class_c_scheduling_type()
.from_proto(),
multicast_dr: req_dp.multicast_dr as i16,
multicast_class_b_ping_slot_nb_k: req_dp.multicast_class_b_ping_slot_nb_k as i16,
multicast_class_b_ping_slot_periodicity: req_dp.multicast_class_b_ping_slot_periodicity
as i16,
multicast_frequency: req_dp.multicast_frequency as i64,
multicast_timeout: req_dp.multicast_timeout as i16,
unicast_max_retry_count: req_dp.unicast_max_retry_count as i16,

View File

@ -193,17 +193,17 @@ impl FromProto<Aggregation> for common::Aggregation {
}
}
impl ToProto<common::MType> for lrwn::MType {
fn to_proto(self) -> common::MType {
impl ToProto<common::FType> for lrwn::FType {
fn to_proto(self) -> common::FType {
match self {
lrwn::MType::JoinRequest => common::MType::JoinRequest,
lrwn::MType::JoinAccept => common::MType::JoinAccept,
lrwn::MType::UnconfirmedDataUp => common::MType::UnconfirmedDataUp,
lrwn::MType::UnconfirmedDataDown => common::MType::UnconfirmedDataDown,
lrwn::MType::ConfirmedDataUp => common::MType::ConfirmedDataUp,
lrwn::MType::ConfirmedDataDown => common::MType::ConfirmedDataDown,
lrwn::MType::RejoinRequest => common::MType::RejoinRequest,
lrwn::MType::Proprietary => common::MType::Proprietary,
lrwn::FType::JoinRequest => common::FType::JoinRequest,
lrwn::FType::JoinAccept => common::FType::JoinAccept,
lrwn::FType::UnconfirmedDataUp => common::FType::UnconfirmedDataUp,
lrwn::FType::UnconfirmedDataDown => common::FType::UnconfirmedDataDown,
lrwn::FType::ConfirmedDataUp => common::FType::ConfirmedDataUp,
lrwn::FType::ConfirmedDataDown => common::FType::ConfirmedDataDown,
lrwn::FType::RejoinRequest => common::FType::RejoinRequest,
lrwn::FType::Proprietary => common::FType::Proprietary,
}
}
}

View File

@ -61,14 +61,7 @@ impl MulticastGroupService for MulticastGroup {
.to_string(),
dr: req_mg.dr as i16,
frequency: req_mg.frequency as i64,
class_b_ping_slot_nb_k: if req_mg.class_b_ping_slot_period != 0 {
// For backwards compatibility.
(req_mg.class_b_ping_slot_period / 32)
.checked_ilog2()
.unwrap_or_default()
} else {
req_mg.class_b_ping_slot_nb_k
} as i16,
class_b_ping_slot_periodicity: req_mg.class_b_ping_slot_periodicity as i16,
class_c_scheduling_type: req_mg.class_c_scheduling_type().from_proto(),
..Default::default()
};
@ -121,8 +114,7 @@ impl MulticastGroupService for MulticastGroup {
.into(),
dr: mg.dr as u32,
frequency: mg.frequency as u32,
class_b_ping_slot_period: (1 << (mg.class_b_ping_slot_nb_k as u32)) * 32,
class_b_ping_slot_nb_k: mg.class_b_ping_slot_nb_k as u32,
class_b_ping_slot_periodicity: mg.class_b_ping_slot_periodicity as u32,
class_c_scheduling_type: mg.class_c_scheduling_type.to_proto().into(),
}),
created_at: Some(helpers::datetime_to_prost_timestamp(&mg.created_at)),
@ -168,14 +160,7 @@ impl MulticastGroupService for MulticastGroup {
.to_string(),
dr: req_mg.dr as i16,
frequency: req_mg.frequency as i64,
class_b_ping_slot_nb_k: if req_mg.class_b_ping_slot_period != 0 {
// For backwards compatibility.
(req_mg.class_b_ping_slot_period / 32)
.checked_ilog2()
.unwrap_or_default()
} else {
req_mg.class_b_ping_slot_nb_k
} as i16,
class_b_ping_slot_periodicity: req_mg.class_b_ping_slot_periodicity as i16,
class_c_scheduling_type: req_mg.class_c_scheduling_type().from_proto(),
..Default::default()
})
@ -606,7 +591,7 @@ pub mod test {
group_type: api::MulticastGroupType::ClassC.into(),
dr: 3,
frequency: 868300000,
class_b_ping_slot_nb_k: 1,
class_b_ping_slot_periodicity: 1,
class_c_scheduling_type: api::MulticastGroupSchedulingType::GpsTime.into(),
..Default::default()
}),
@ -636,8 +621,7 @@ pub mod test {
group_type: api::MulticastGroupType::ClassC.into(),
dr: 3,
frequency: 868300000,
class_b_ping_slot_nb_k: 1,
class_b_ping_slot_period: 64,
class_b_ping_slot_periodicity: 1,
class_c_scheduling_type: api::MulticastGroupSchedulingType::GpsTime.into(),
}),
get_resp.get_ref().multicast_group
@ -659,8 +643,7 @@ pub mod test {
group_type: api::MulticastGroupType::ClassB.into(),
dr: 2,
frequency: 868200000,
class_b_ping_slot_nb_k: 2,
class_b_ping_slot_period: 0,
class_b_ping_slot_periodicity: 2,
class_c_scheduling_type: api::MulticastGroupSchedulingType::Delay.into(),
}),
},
@ -688,8 +671,7 @@ pub mod test {
group_type: api::MulticastGroupType::ClassB.into(),
dr: 2,
frequency: 868200000,
class_b_ping_slot_nb_k: 2,
class_b_ping_slot_period: 128,
class_b_ping_slot_periodicity: 2,
class_c_scheduling_type: api::MulticastGroupSchedulingType::Delay.into(),
}),
get_resp.get_ref().multicast_group

View File

@ -149,7 +149,9 @@ impl Flow {
group_type: self.fuota_deployment.multicast_group_type.clone(),
frequency: self.fuota_deployment.multicast_frequency,
dr: self.fuota_deployment.multicast_dr,
class_b_ping_slot_nb_k: self.fuota_deployment.multicast_class_b_ping_slot_nb_k,
class_b_ping_slot_periodicity: self
.fuota_deployment
.multicast_class_b_ping_slot_periodicity,
class_c_scheduling_type: self.fuota_deployment.multicast_class_c_scheduling_type,
..Default::default()
})
@ -577,7 +579,7 @@ impl Flow {
time_out_periodicity:
multicastsetup::v1::McClassBSessionReqPayloadTimeOutPeriodicity {
time_out: self.fuota_deployment.multicast_timeout as u8,
periodicity: self.fuota_deployment.multicast_class_b_ping_slot_nb_k
periodicity: self.fuota_deployment.multicast_class_b_ping_slot_periodicity
as u8,
},
dl_frequ: self.fuota_deployment.multicast_frequency as u32,
@ -619,7 +621,7 @@ impl Flow {
time_out_periodicity:
multicastsetup::v2::McClassBSessionReqPayloadTimeOutPeriodicity {
time_out: self.fuota_deployment.multicast_timeout as u8,
periodicity: self.fuota_deployment.multicast_class_b_ping_slot_nb_k
periodicity: self.fuota_deployment.multicast_class_b_ping_slot_periodicity
as u8,
},
dl_frequ: self.fuota_deployment.multicast_frequency as u32,

View File

@ -265,7 +265,7 @@ async fn import_device(
supports_class_b: prof.supports_class_b,
supports_class_c: prof.supports_class_c,
class_b_timeout: prof.class_b_timeout as i32,
class_b_ping_slot_nb_k: match prof.ping_slot_period {
class_b_ping_slot_periodicity: match prof.ping_slot_period {
128 => 7,
64 => 6,
32 => 5,

View File

@ -94,7 +94,7 @@ pub struct ProfileAbp {
#[derive(Default, Deserialize)]
pub struct ProfileClassB {
pub timeout_secs: usize,
pub ping_slot_nb_k: usize,
pub ping_slot_periodicity: usize,
pub ping_slot_dr: usize,
pub ping_slot_freq: usize,
}
@ -239,7 +239,7 @@ async fn handle_profile(
supports_class_b: profile_conf.profile.supports_class_b,
supports_class_c: profile_conf.profile.supports_class_c,
class_b_timeout: profile_conf.profile.class_b.timeout_secs as i32,
class_b_ping_slot_nb_k: profile_conf.profile.class_b.ping_slot_nb_k as i32,
class_b_ping_slot_periodicity: profile_conf.profile.class_b.ping_slot_periodicity as i32,
class_b_ping_slot_dr: profile_conf.profile.class_b.ping_slot_dr as i16,
class_b_ping_slot_freq: profile_conf.profile.class_b.ping_slot_freq as i64,
class_c_timeout: profile_conf.profile.class_c.timeout_secs as i32,

View File

@ -352,6 +352,7 @@ pub struct AmqpIntegration {
pub url: String,
pub json: bool,
pub event_routing_key: String,
pub exchange: String,
}
impl Default for AmqpIntegration {
@ -361,6 +362,7 @@ impl Default for AmqpIntegration {
json: true,
event_routing_key: "application.{{application_id}}.device.{{dev_eui}}.event.{{event}}"
.to_string(),
exchange: "amq.topic".to_string(),
}
}
}

View File

@ -707,7 +707,8 @@ impl Data {
fn set_phy_payloads(&mut self) -> Result<()> {
trace!("Setting downlink PHYPayloads");
let mut f_pending = self.more_device_queue_items;
let ds = self.device.get_device_session()?;
let dev_addr = self.device.get_dev_addr()?;
let ds = self.device.get_device_session_mut()?;
for item in self.downlink_frame_items.iter_mut() {
let mut mac_size: usize = 0;
@ -729,18 +730,20 @@ impl Data {
for mac in &**mac_set {
mac_commands.push(mac.clone());
}
mac_command::set_pending(ds, mac_set)?;
}
// LoRaWAN MHDR
let mut mhdr = lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
};
// LoRaWAN MAC payload
let mut mac_pl = lrwn::MACPayload {
fhdr: lrwn::FHDR {
devaddr: self.device.get_dev_addr()?,
devaddr: dev_addr,
f_cnt: ds.n_f_cnt_down,
f_ctrl: lrwn::FCtrl {
adr: !self.network_conf.adr_disabled,
@ -791,7 +794,7 @@ impl Data {
mac_pl.frm_payload = Some(lrwn::FRMPayload::Raw(qi.data.clone()));
if qi.confirmed {
mhdr.m_type = lrwn::MType::ConfirmedDataDown;
mhdr.f_type = lrwn::FType::ConfirmedDataDown;
}
item.remaining_payload_size -= qi.data.len();
@ -864,7 +867,7 @@ impl Data {
for item in self.downlink_frame.items.iter_mut() {
let mut relay_phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -912,7 +915,7 @@ impl Data {
for item in self.downlink_frame_items.iter_mut() {
let mut relay_phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1196,8 +1199,6 @@ impl Data {
if let Some(block) =
maccommand::new_channel::request(3, &current_channels, &wanted_channels)
{
mac_command::set_pending(&self.device.dev_eui, lrwn::CID::NewChannelReq, &block)
.await?;
self.mac_commands.push(block);
}
@ -1207,7 +1208,7 @@ impl Data {
// Note: this must come before ADR!
async fn _request_channel_mask_reconfiguration(&mut self) -> Result<()> {
trace!("Requesting channel-mask reconfiguration");
let ds = self.device.get_device_session()?;
let ds = self.device.get_device_session_mut()?;
let enabled_uplink_channel_indices: Vec<usize> = ds
.enabled_uplink_channel_indices
@ -1239,7 +1240,6 @@ impl Data {
.collect(),
);
mac_command::set_pending(&self.device.dev_eui, lrwn::CID::LinkADRReq, &set).await?;
self.mac_commands.push(set);
Ok(())
@ -1257,12 +1257,15 @@ impl Data {
.get_data_rate(self.uplink_frame_set.as_ref().unwrap().dr)?;
let ufs = self.uplink_frame_set.as_ref().unwrap();
let ds = self.device.get_device_session()?;
let dev_eui = self.device.dev_eui;
let device_variables = self.device.variables.into_hashmap();
let ds = self.device.get_device_session_mut()?;
let req = adr::Request {
dev_eui,
device_variables,
region_config_id: ufs.region_config_id.clone(),
region_common_name: ufs.region_common_name,
dev_eui: self.device.dev_eui,
mac_version: self.device_profile.mac_version,
reg_params_revision: self.device_profile.reg_params_revision,
adr: ds.adr,
@ -1291,7 +1294,6 @@ impl Data {
max_dr: self.network_conf.max_dr,
uplink_history: ds.uplink_adr_history.clone(),
skip_f_cnt_check: ds.skip_f_cnt_check,
device_variables: self.device.variables.into_hashmap(),
};
let resp = adr::handle(&self.device_profile.adr_algorithm_id, &req).await;
@ -1304,24 +1306,14 @@ impl Data {
{
let mut adr_set = false;
for set in self.mac_commands.iter_mut() {
let mut is_link_adr_set = false;
for mac in &mut **set {
if let lrwn::MACCommand::LinkADRReq(pl) = mac {
pl.dr = resp.dr;
pl.tx_power = resp.tx_power_index;
pl.redundancy.nb_rep = resp.nb_trans;
adr_set = true;
is_link_adr_set = true;
}
}
if is_link_adr_set {
// We need to update the pending mac-command.
mac_command::set_pending(&self.device.dev_eui, lrwn::CID::LinkADRReq, set)
.await?;
}
}
// There was no existing LinkADRReq to be sent, we need to construct a new one.
@ -1358,7 +1350,6 @@ impl Data {
},
)]);
mac_command::set_pending(&self.device.dev_eui, lrwn::CID::LinkADRReq, &set).await?;
self.mac_commands.push(set);
}
}
@ -1406,7 +1397,7 @@ impl Data {
async fn _request_rejoin_param_setup(&mut self) -> Result<()> {
trace!("Requesting rejoin param setup");
let ds = self.device.get_device_session()?;
let ds = self.device.get_device_session_mut()?;
// Rejoin-request is disabled or device does not support LoRaWAN 1.1.
if !self.network_conf.rejoin_request.enabled
@ -1423,8 +1414,6 @@ impl Data {
self.network_conf.rejoin_request.max_time_n,
self.network_conf.rejoin_request.max_count_n,
);
mac_command::set_pending(&self.device.dev_eui, lrwn::CID::RejoinParamSetupReq, &set)
.await?;
self.mac_commands.push(set);
}
@ -1434,7 +1423,7 @@ impl Data {
async fn _set_ping_slot_parameters(&mut self) -> Result<()> {
trace!("Setting ping-slot parameters");
let ds = self.device.get_device_session()?;
let ds = self.device.get_device_session_mut()?;
if !self.device_profile.supports_class_b {
return Ok(());
@ -1447,8 +1436,6 @@ impl Data {
self.network_conf.class_b.ping_slot_dr,
self.network_conf.class_b.ping_slot_frequency,
);
mac_command::set_pending(&self.device.dev_eui, lrwn::CID::PingSlotChannelReq, &set)
.await?;
self.mac_commands.push(set);
}
@ -1457,7 +1444,7 @@ impl Data {
async fn _set_rx_parameters(&mut self) -> Result<()> {
trace!("Setting rx parameters");
let ds = self.device.get_device_session()?;
let ds = self.device.get_device_session_mut()?;
if ds.rx2_frequency != self.network_conf.rx2_frequency
|| ds.rx2_dr as u8 != self.network_conf.rx2_dr
@ -1468,8 +1455,6 @@ impl Data {
self.network_conf.rx2_frequency,
self.network_conf.rx2_dr,
);
mac_command::set_pending(&self.device.dev_eui, lrwn::CID::RxParamSetupReq, &set)
.await?;
self.mac_commands.push(set);
}
@ -1481,8 +1466,6 @@ impl Data {
if dev_rx1_delay != req_rx1_delay {
let set = maccommand::rx_timing_setup::request(req_rx1_delay);
mac_command::set_pending(&self.device.dev_eui, lrwn::CID::RxTimingSetupReq, &set)
.await?;
self.mac_commands.push(set);
}
@ -1491,7 +1474,7 @@ impl Data {
async fn _set_tx_parameters(&mut self) -> Result<()> {
trace!("Setting tx parameters");
let ds = self.device.get_device_session()?;
let ds = self.device.get_device_session_mut()?;
if !self
.region_conf
@ -1512,8 +1495,6 @@ impl Data {
self.network_conf.downlink_dwell_time_400ms,
uplink_eirp_index,
);
mac_command::set_pending(&self.device.dev_eui, lrwn::CID::TxParamSetupReq, &set)
.await?;
self.mac_commands.push(set);
}
@ -1567,8 +1548,8 @@ impl Data {
|| rd.uplink_limit_reload_rate
!= device.relay_ed_uplink_limit_reload_rate as u32
{
let d = device::get(&device.dev_eui).await?;
let ds = match d.get_device_session() {
let mut d = device::get(&device.dev_eui).await?;
let ds = match d.get_device_session_mut() {
Ok(v) => v,
Err(_) => {
// It is valid that the device is no longer activated.
@ -1595,13 +1576,17 @@ impl Data {
},
),
]);
mac_command::set_pending(
&dev_eui,
lrwn::CID::UpdateUplinkListReq,
&set,
self.mac_commands.push(set);
// Update device-session of device.
device::partial_update(
d.dev_eui,
&device::DeviceChangeset {
device_session: Some(d.device_session.clone()),
..Default::default()
},
)
.await?;
self.mac_commands.push(set);
rd.dev_addr = dev_addr.to_vec();
rd.root_wor_s_key = root_wor_s_key.to_vec();
@ -1651,8 +1636,6 @@ impl Data {
root_wor_s_key,
},
)]);
mac_command::set_pending(&dev_eui, lrwn::CID::UpdateUplinkListReq, &set)
.await?;
self.mac_commands.push(set);
ds.relay
@ -1788,8 +1771,6 @@ impl Data {
if !commands.is_empty() {
let set = lrwn::MACCommandSet::new(commands);
mac_command::set_pending(&self.device.dev_eui, lrwn::CID::CtrlUplinkListReq, &set)
.await?;
self.mac_commands.push(set);
}
@ -1799,7 +1780,6 @@ impl Data {
async fn _configure_fwd_limit_req(&mut self) -> Result<()> {
trace!("Configuring Relay Fwd Limit");
let dev_eui = self.device.dev_eui;
let ds = self.device.get_device_session_mut()?;
let relay_params = self.device_profile.relay_params.clone().unwrap_or_default();
@ -1843,7 +1823,6 @@ impl Data {
},
},
)]);
mac_command::set_pending(&dev_eui, lrwn::CID::ConfigureFwdLimitReq, &set).await?;
self.mac_commands.push(set);
}
@ -1915,7 +1894,6 @@ impl Data {
}
let set = lrwn::MACCommandSet::new(commands);
mac_command::set_pending(&self.device.dev_eui, lrwn::CID::FilterListReq, &set).await?;
self.mac_commands.push(set);
// The deletes needs to be processed before we can add new entries.
@ -1944,8 +1922,6 @@ impl Data {
filter_list_eui: vec![],
},
)]);
mac_command::set_pending(&self.device.dev_eui, lrwn::CID::FilterListReq, &set)
.await?;
self.mac_commands.push(set);
// Return because we can't add multiple sets and if we would combine
@ -1977,7 +1953,6 @@ impl Data {
filter_list_eui: eui,
},
)]);
mac_command::set_pending(&dev_eui, lrwn::CID::FilterListReq, &set).await?;
self.mac_commands.push(set);
f.join_eui = device.join_eui.to_vec();
@ -2009,7 +1984,6 @@ impl Data {
filter_list_eui: eui,
},
)]);
mac_command::set_pending(&dev_eui, lrwn::CID::FilterListReq, &set).await?;
self.mac_commands.push(set);
ds.relay
@ -2037,7 +2011,6 @@ impl Data {
async fn _update_relay_conf(&mut self) -> Result<()> {
trace!("Updating Relay Conf");
let dev_eui = self.device.dev_eui;
let ds = self.device.get_device_session_mut()?;
let relay_params = self.device_profile.relay_params.clone().unwrap_or_default();
@ -2075,7 +2048,6 @@ impl Data {
second_ch_freq: relay_params.second_channel_freq,
},
)]);
mac_command::set_pending(&dev_eui, lrwn::CID::RelayConfReq, &set).await?;
self.mac_commands.push(set);
}
@ -2087,7 +2059,6 @@ impl Data {
async fn _update_end_device_conf(&mut self) -> Result<()> {
trace!("Updating End Device Conf");
let dev_eui = self.device.dev_eui;
let ds = self.device.get_device_session_mut()?;
let relay_params = self.device_profile.relay_params.clone().unwrap_or_default();
@ -2124,7 +2095,6 @@ impl Data {
second_ch_freq: relay_params.second_channel_freq,
},
)]);
mac_command::set_pending(&dev_eui, lrwn::CID::EndDeviceConfReq, &set).await?;
self.mac_commands.push(set);
}

View File

@ -466,7 +466,7 @@ impl JoinAccept<'_> {
let mut relay_phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -199,7 +199,7 @@ impl Multicast {
let mut phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -3,7 +3,7 @@ use chrono::{Duration, Utc};
use tracing::{error, info, span, trace, Instrument, Level};
use uuid::Uuid;
use lrwn::{AES128Key, MType, Payload, PhyPayload, EUI64};
use lrwn::{AES128Key, FType, Payload, PhyPayload, EUI64};
use crate::api::helpers::ToProto;
use crate::storage::{
@ -589,13 +589,13 @@ impl TxAck {
tx_info: dfi.tx_info.clone(),
downlink_id: gw_df.downlink_id,
gateway_id: gw_df.gateway_id.clone(),
m_type: match &phy.mhdr.m_type {
MType::JoinAccept => common::MType::JoinAccept,
MType::UnconfirmedDataDown => common::MType::UnconfirmedDataDown,
MType::ConfirmedDataDown => common::MType::ConfirmedDataDown,
MType::Proprietary => common::MType::Proprietary,
f_type: match &phy.mhdr.f_type {
FType::JoinAccept => common::FType::JoinAccept,
FType::UnconfirmedDataDown => common::FType::UnconfirmedDataDown,
FType::ConfirmedDataDown => common::FType::ConfirmedDataDown,
FType::Proprietary => common::FType::Proprietary,
_ => {
return Err(anyhow!("Unepxected MType: {}", phy.mhdr.m_type));
return Err(anyhow!("Unepxected FType: {}", phy.mhdr.f_type));
}
}
.into(),
@ -658,7 +658,7 @@ impl TxAck {
tx_info: dfl.tx_info.clone(),
downlink_id: dfl.downlink_id,
gateway_id: dfl.gateway_id.clone(),
m_type: dfl.m_type,
f_type: dfl.f_type,
dev_addr: dfl.dev_addr.clone(),
dev_eui: dfl.dev_eui.clone(),
plaintext_f_opts: true,
@ -719,7 +719,7 @@ impl TxAck {
} else {
0
} as u32,
message_type: phy.mhdr.m_type.to_proto().into(),
frame_type: phy.mhdr.f_type.to_proto().into(),
gateway_id: df.downlink_frame.as_ref().unwrap().gateway_id.clone(),
};
@ -803,15 +803,15 @@ impl TxAck {
}
fn is_unconfirmed_downlink(&self) -> bool {
if self.phy_payload.as_ref().unwrap().mhdr.m_type == lrwn::MType::UnconfirmedDataDown {
if self.phy_payload.as_ref().unwrap().mhdr.f_type == lrwn::FType::UnconfirmedDataDown {
return true;
}
false
}
fn is_unconfirmed_downlink_relayed(&self) -> bool {
if self.phy_payload_relayed.as_ref().unwrap().mhdr.m_type
== lrwn::MType::UnconfirmedDataDown
if self.phy_payload_relayed.as_ref().unwrap().mhdr.f_type
== lrwn::FType::UnconfirmedDataDown
{
return true;
}
@ -819,14 +819,14 @@ impl TxAck {
}
fn is_confirmed_downlink(&self) -> bool {
if self.phy_payload.as_ref().unwrap().mhdr.m_type == lrwn::MType::ConfirmedDataDown {
if self.phy_payload.as_ref().unwrap().mhdr.f_type == lrwn::FType::ConfirmedDataDown {
return true;
}
false
}
fn is_confirmed_downlink_relayed(&self) -> bool {
if self.phy_payload_relayed.as_ref().unwrap().mhdr.m_type == lrwn::MType::ConfirmedDataDown
if self.phy_payload_relayed.as_ref().unwrap().mhdr.f_type == lrwn::FType::ConfirmedDataDown
{
return true;
}

View File

@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::io::Cursor;
use std::sync::{LazyLock, RwLock};
use std::time::Duration;
@ -352,7 +351,7 @@ async fn message_callback(
.inc();
let mut event = match json {
true => serde_json::from_slice(&p.payload)?,
false => chirpstack_api::gw::UplinkFrame::decode(&mut Cursor::new(&p.payload))?,
false => chirpstack_api::gw::UplinkFrame::decode(p.payload.as_ref())?,
};
if v4_migrate {
@ -377,7 +376,7 @@ async fn message_callback(
.inc();
let mut event = match json {
true => serde_json::from_slice(&p.payload)?,
false => chirpstack_api::gw::GatewayStats::decode(&mut Cursor::new(&p.payload))?,
false => chirpstack_api::gw::GatewayStats::decode(p.payload.as_ref())?,
};
if v4_migrate {
@ -401,7 +400,7 @@ async fn message_callback(
.inc();
let mut event = match json {
true => serde_json::from_slice(&p.payload)?,
false => chirpstack_api::gw::DownlinkTxAck::decode(&mut Cursor::new(&p.payload))?,
false => chirpstack_api::gw::DownlinkTxAck::decode(p.payload.as_ref())?,
};
if v4_migrate {
@ -410,18 +409,18 @@ async fn message_callback(
set_gateway_json(&event.gateway_id, json);
tokio::spawn(downlink::tx_ack::TxAck::handle(event));
} else if topic.ends_with("/mesh-heartbeat") {
} else if topic.ends_with("/mesh") {
EVENT_COUNTER
.get_or_create(&EventLabels {
event: "mesh-heartbeat".to_string(),
event: "mesh".to_string(),
})
.inc();
let event = match json {
true => serde_json::from_slice(&p.payload)?,
false => chirpstack_api::gw::MeshHeartbeat::decode(&mut Cursor::new(&p.payload))?,
false => chirpstack_api::gw::MeshEvent::decode(p.payload.as_ref())?,
};
tokio::spawn(uplink::mesh::MeshHeartbeat::handle(event));
tokio::spawn(uplink::mesh::Mesh::handle(event));
} else {
return Err(anyhow!("Unknown event type"));
}

View File

@ -27,6 +27,7 @@ pub struct Integration<'a> {
templates: Handlebars<'a>,
json: bool,
url: String,
exchange: String,
}
#[derive(Serialize)]
@ -49,6 +50,7 @@ impl<'a> Integration<'a> {
templates,
url: conf.url.clone(),
json: conf.json,
exchange: conf.exchange.clone(),
};
i.connect().await?;
@ -90,7 +92,7 @@ impl<'a> Integration<'a> {
.as_ref()
.unwrap()
.basic_publish(
"amq.topic",
&self.exchange,
&routing_key,
BasicPublishOptions::default(),
b,

View File

@ -20,6 +20,7 @@ fn get_client() -> Client {
.get_or_init(|| {
Client::builder()
.timeout(Duration::from_secs(5))
.use_rustls_tls()
.build()
.unwrap()
})

View File

@ -106,7 +106,7 @@ pub mod test {
ch: 0,
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -53,7 +53,7 @@ pub mod test {
ch: 0,
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -338,7 +338,7 @@ pub mod test {
ch: 0,
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -77,7 +77,7 @@ pub mod test {
ch: 0,
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -77,7 +77,7 @@ pub async fn handle_uplink(
);
// Get pending mac-command block, this could return None.
let pending = match mac_command::get_pending(&dev.dev_eui, cid).await {
let pending = match mac_command::get_pending(dev.get_device_session_mut()?, cid).await {
Ok(v) => v,
Err(e) => {
error!(dev_eui = %dev.dev_eui, cid = %cid, error = %e, "Get pending mac-command block error");
@ -85,13 +85,6 @@ pub async fn handle_uplink(
}
};
// Delete the pending mac-command.
if pending.is_some() {
if let Err(e) = mac_command::delete_pending(&dev.dev_eui, cid).await {
error!(dev_eui = %dev.dev_eui, cid = %cid, error = %e, "Delete pending mac-command error");
}
}
// Handle the mac-command, which might return a block to answer the uplink mac-command
// request.
let res = match handle(
@ -182,7 +175,7 @@ pub mod test {
ch: 0,
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -80,7 +80,7 @@ pub mod test {
class_b_params: Some(fields::ClassBParams {
ping_slot_dr: 2,
ping_slot_freq: 868100000,
ping_slot_nb_k: 1,
ping_slot_periodicity: 6,
timeout: 0,
}),
..Default::default()

View File

@ -327,6 +327,15 @@ pub async fn get_for_phypayload_and_incr_f_cnt_up(
return Err(Error::InvalidPayload("MacPayload".to_string()));
};
// We calculate the scheduler_run_after timestamp, such that we can update
// it directly when updating the device-session (to update the frame-counter).
// This way, we limit the risk of overlapping Class-A downlinks with Class-B / -C
// downlinks.
let conf = config::get();
let scheduler_run_after = Utc::now()
+ Duration::from_std(conf.network.scheduler.class_a_lock_duration)
.map_err(anyhow::Error::new)?;
let mut c = get_async_db_conn().await?;
db_transaction::<ValidationStatus, Error, _>(&mut c, |c| {
@ -427,10 +436,20 @@ pub async fn get_for_phypayload_and_incr_f_cnt_up(
let ds_f_cnt_up = ds.f_cnt_up;
ds.f_cnt_up = full_f_cnt + 1;
let _ = diesel::update(device::dsl::device.find(d.dev_eui))
.set(device::device_session.eq(&ds.clone()))
.execute(c)
.await?;
if scheduler_run_after > d.scheduler_run_after.unwrap_or_default() {
let _ = diesel::update(device::dsl::device.find(d.dev_eui))
.set((
device::device_session.eq(&ds.clone()),
device::scheduler_run_after.eq(&scheduler_run_after),
))
.execute(c)
.await?;
} else {
let _ = diesel::update(device::dsl::device.find(d.dev_eui))
.set(device::device_session.eq(&ds.clone()))
.execute(c)
.await?;
}
// We do return the device-session with original frame-counter
ds.f_cnt_up = ds_f_cnt_up;
@ -711,17 +730,37 @@ pub async fn list(
true => match order_by {
OrderBy::Name => q.order_by(device::dsl::name.desc()),
OrderBy::DevEui => q.order_by(device::dsl::dev_eui.desc()),
OrderBy::LastSeenAt => q
.order_by(device::dsl::last_seen_at.desc())
.then_order_by(device::dsl::name),
OrderBy::LastSeenAt => {
#[cfg(feature = "postgres")]
{
q.order_by(device::dsl::last_seen_at.desc().nulls_last())
.then_order_by(device::dsl::name)
}
#[cfg(feature = "sqlite")]
{
q.order_by(device::dsl::last_seen_at.desc())
.then_order_by(device::dsl::name)
}
}
OrderBy::DeviceProfileName => q.order_by(device_profile::dsl::name.desc()),
},
false => match order_by {
OrderBy::Name => q.order_by(device::dsl::name),
OrderBy::DevEui => q.order_by(device::dsl::dev_eui),
OrderBy::LastSeenAt => q
.order_by(device::dsl::last_seen_at)
.then_order_by(device::dsl::name),
OrderBy::LastSeenAt => {
#[cfg(feature = "postgres")]
{
q.order_by(device::dsl::last_seen_at.asc().nulls_first())
.then_order_by(device::dsl::name)
}
#[cfg(feature = "sqlite")]
{
q.order_by(device::dsl::last_seen_at.asc())
.then_order_by(device::dsl::name)
}
}
OrderBy::DeviceProfileName => q.order_by(device_profile::dsl::name),
},
};
@ -1643,7 +1682,7 @@ pub mod test {
println!("> {}", tst.name);
let mut phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -110,7 +110,7 @@ impl DeviceProfile {
if let Some(class_b_params) = &self.class_b_params {
ds.class_b_ping_slot_dr = class_b_params.ping_slot_dr as u32;
ds.class_b_ping_slot_freq = class_b_params.ping_slot_freq;
ds.class_b_ping_slot_nb = 1 << class_b_params.ping_slot_nb_k as u32;
ds.class_b_ping_slot_nb = 1 << (7 - class_b_params.ping_slot_periodicity) as u32;
}
if let Some(relay_params) = &self.relay_params {

View File

@ -37,7 +37,7 @@ pub struct DeviceProfileTemplate {
pub supports_class_b: bool,
pub supports_class_c: bool,
pub class_b_timeout: i32,
pub class_b_ping_slot_nb_k: i32,
pub class_b_ping_slot_periodicity: i32,
pub class_b_ping_slot_dr: i16,
pub class_b_ping_slot_freq: i64,
pub class_c_timeout: i32,
@ -100,7 +100,7 @@ impl Default for DeviceProfileTemplate {
supports_class_b: false,
supports_class_c: false,
class_b_timeout: 0,
class_b_ping_slot_nb_k: 0,
class_b_ping_slot_periodicity: 0,
class_b_ping_slot_dr: 0,
class_b_ping_slot_freq: 0,
class_c_timeout: 0,
@ -169,7 +169,8 @@ pub async fn upsert(dp: DeviceProfileTemplate) -> Result<DeviceProfileTemplate,
device_profile_template::supports_class_b.eq(&dp.supports_class_b),
device_profile_template::supports_class_c.eq(&dp.supports_class_c),
device_profile_template::class_b_timeout.eq(&dp.class_b_timeout),
device_profile_template::class_b_ping_slot_nb_k.eq(&dp.class_b_ping_slot_nb_k),
device_profile_template::class_b_ping_slot_periodicity
.eq(&dp.class_b_ping_slot_periodicity),
device_profile_template::class_b_ping_slot_dr.eq(&dp.class_b_ping_slot_dr),
device_profile_template::class_b_ping_slot_freq.eq(&dp.class_b_ping_slot_freq),
device_profile_template::class_c_timeout.eq(&dp.class_c_timeout),
@ -224,7 +225,8 @@ pub async fn update(dp: DeviceProfileTemplate) -> Result<DeviceProfileTemplate,
device_profile_template::supports_class_b.eq(&dp.supports_class_b),
device_profile_template::supports_class_c.eq(&dp.supports_class_c),
device_profile_template::class_b_timeout.eq(&dp.class_b_timeout),
device_profile_template::class_b_ping_slot_nb_k.eq(&dp.class_b_ping_slot_nb_k),
device_profile_template::class_b_ping_slot_periodicity
.eq(&dp.class_b_ping_slot_periodicity),
device_profile_template::class_b_ping_slot_dr.eq(&dp.class_b_ping_slot_dr),
device_profile_template::class_b_ping_slot_freq.eq(&dp.class_b_ping_slot_freq),
device_profile_template::class_c_timeout.eq(&dp.class_c_timeout),

View File

@ -24,7 +24,10 @@ pub async fn save(df: &internal::DownlinkFrame) -> Result<()> {
pub async fn get_and_del(id: u32) -> Result<internal::DownlinkFrame, Error> {
let key = redis_key(format!("frame:{}", id));
let v: Vec<u8> = redis::cmd("GETDEL")
let (v, _): (Vec<u8>, u8) = redis::pipe()
.cmd("GET")
.arg(key.clone())
.cmd("DEL")
.arg(key)
.query_async(&mut get_async_redis_conn().await?)
.await?;

View File

@ -61,7 +61,8 @@ impl serialize::ToSql<Text, Sqlite> for AbpParams {
#[cfg_attr(feature = "sqlite", diesel(sql_type = Text))]
pub struct ClassBParams {
pub timeout: u16,
pub ping_slot_nb_k: u8,
#[serde(alias = "ping_slot_nb_k")]
pub ping_slot_periodicity: u8,
pub ping_slot_dr: u8,
pub ping_slot_freq: u32,
}

View File

@ -33,7 +33,7 @@ pub struct FuotaDeployment {
pub multicast_group_type: String,
pub multicast_class_c_scheduling_type: fields::MulticastGroupSchedulingType,
pub multicast_dr: i16,
pub multicast_class_b_ping_slot_nb_k: i16,
pub multicast_class_b_ping_slot_periodicity: i16,
pub multicast_frequency: i64,
pub multicast_timeout: i16,
pub multicast_session_start: Option<DateTime<Utc>>,
@ -68,7 +68,7 @@ impl Default for FuotaDeployment {
multicast_group_type: "".into(),
multicast_class_c_scheduling_type: fields::MulticastGroupSchedulingType::DELAY,
multicast_dr: 0,
multicast_class_b_ping_slot_nb_k: 0,
multicast_class_b_ping_slot_periodicity: 0,
multicast_frequency: 0,
multicast_timeout: 0,
multicast_session_start: None,
@ -222,8 +222,8 @@ pub async fn update_deployment(d: FuotaDeployment) -> Result<FuotaDeployment, Er
fuota_deployment::multicast_class_c_scheduling_type
.eq(&d.multicast_class_c_scheduling_type),
fuota_deployment::multicast_dr.eq(&d.multicast_dr),
fuota_deployment::multicast_class_b_ping_slot_nb_k
.eq(&d.multicast_class_b_ping_slot_nb_k),
fuota_deployment::multicast_class_b_ping_slot_periodicity
.eq(&d.multicast_class_b_ping_slot_periodicity),
fuota_deployment::multicast_frequency.eq(&d.multicast_frequency),
fuota_deployment::multicast_timeout.eq(&d.multicast_timeout),
fuota_deployment::multicast_session_start.eq(&d.multicast_session_start),
@ -765,7 +765,7 @@ pub fn get_multicast_timeout(d: &FuotaDeployment) -> Result<usize> {
match d.multicast_group_type.as_ref() {
"B" => {
// Calculate number of ping-slots per beacon period.
let nb_ping_slots = 1 << (d.multicast_class_b_ping_slot_nb_k as usize);
let nb_ping_slots = 1 << (7 - d.multicast_class_b_ping_slot_periodicity as usize);
// Calculate number of beacon-periods needed.
// One beacon period is added as the first ping-slot might be in the next beacon-period.
@ -1221,7 +1221,7 @@ mod test {
name: "Class-B - 1 / beacon period - 15 fragments".into(),
deployment: FuotaDeployment {
multicast_group_type: "B".into(),
multicast_class_b_ping_slot_nb_k: 0,
multicast_class_b_ping_slot_periodicity: 7,
fragmentation_fragment_size: 10,
fragmentation_redundancy_percentage: 50,
payload: vec![0; 100],
@ -1234,7 +1234,7 @@ mod test {
name: "Class-B - 1 / beacon period - 16 fragments".into(),
deployment: FuotaDeployment {
multicast_group_type: "B".into(),
multicast_class_b_ping_slot_nb_k: 0,
multicast_class_b_ping_slot_periodicity: 7,
fragmentation_fragment_size: 10,
fragmentation_redundancy_percentage: 60,
payload: vec![0; 100],
@ -1247,7 +1247,7 @@ mod test {
name: "Class-B - 16 / beacon period - 16 fragments".into(),
deployment: FuotaDeployment {
multicast_group_type: "B".into(),
multicast_class_b_ping_slot_nb_k: 4,
multicast_class_b_ping_slot_periodicity: 3,
fragmentation_fragment_size: 10,
fragmentation_redundancy_percentage: 60,
payload: vec![0; 100],
@ -1260,7 +1260,7 @@ mod test {
name: "Class-B - 16 / beacon period - 17 fragments".into(),
deployment: FuotaDeployment {
multicast_group_type: "B".into(),
multicast_class_b_ping_slot_nb_k: 4,
multicast_class_b_ping_slot_periodicity: 3,
fragmentation_fragment_size: 10,
fragmentation_redundancy_percentage: 70,
payload: vec![0; 100],

View File

@ -365,16 +365,36 @@ pub async fn list(
true => match order_by {
OrderBy::Name => q.order_by(gateway::dsl::name.desc()),
OrderBy::GatewayId => q.order_by(gateway::dsl::gateway_id.desc()),
OrderBy::LastSeenAt => q
.order_by(gateway::dsl::last_seen_at.desc())
.then_order_by(gateway::dsl::name),
OrderBy::LastSeenAt => {
#[cfg(feature = "postgres")]
{
q.order_by(gateway::dsl::last_seen_at.desc().nulls_last())
.then_order_by(gateway::dsl::name)
}
#[cfg(feature = "sqlite")]
{
q.order_by(gateway::dsl::last_seen_at.desc())
.then_order_by(gateway::dsl::name)
}
}
},
false => match order_by {
OrderBy::Name => q.order_by(gateway::dsl::name),
OrderBy::GatewayId => q.order_by(gateway::dsl::gateway_id),
OrderBy::LastSeenAt => q
.order_by(gateway::dsl::last_seen_at)
.then_order_by(gateway::dsl::name),
OrderBy::LastSeenAt => {
#[cfg(feature = "postgres")]
{
q.order_by(gateway::dsl::last_seen_at.asc().nulls_first())
.then_order_by(gateway::dsl::name)
}
#[cfg(feature = "sqlite")]
{
q.order_by(gateway::dsl::last_seen_at.asc())
.then_order_by(gateway::dsl::name)
}
}
},
};
@ -599,7 +619,7 @@ pub mod test {
group_type: "C".into(),
dr: 1,
frequency: 868100000,
class_b_ping_slot_nb_k: 1,
class_b_ping_slot_periodicity: 1,
..Default::default()
})
.await

View File

@ -1,34 +1,24 @@
use anyhow::Result;
use tracing::info;
use super::{get_async_redis_conn, redis_key};
use crate::config;
use lrwn::EUI64;
use chirpstack_api::internal;
pub async fn set_pending(dev_eui: &EUI64, cid: lrwn::CID, set: &lrwn::MACCommandSet) -> Result<()> {
let conf = config::get();
let key = redis_key(format!("device:{}:mac:pending:{}", dev_eui, cid.to_u8()));
let ttl = conf.network.device_session_ttl.as_millis() as usize;
pub fn set_pending(ds: &mut internal::DeviceSession, set: &lrwn::MACCommandSet) -> Result<()> {
let cid = set.cid()?;
let b = set.to_vec()?;
() = redis::cmd("PSETEX")
.arg(key)
.arg(ttl)
.arg(b)
.query_async(&mut get_async_redis_conn().await?)
.await?;
info!(dev_eui = %dev_eui, cid = %cid, "Pending mac-command block set");
ds.mac_command_pending.insert(cid.to_u8().into(), b);
info!(cid = %cid, "Pending mac-command block set");
Ok(())
}
pub async fn get_pending(dev_eui: &EUI64, cid: lrwn::CID) -> Result<Option<lrwn::MACCommandSet>> {
let key = redis_key(format!("device:{}:mac:pending:{}", dev_eui, cid.to_u8()));
let b: Vec<u8> = redis::cmd("GET")
.arg(key)
.query_async(&mut get_async_redis_conn().await?)
.await?;
pub async fn get_pending(
ds: &mut internal::DeviceSession,
cid: lrwn::CID,
) -> Result<Option<lrwn::MACCommandSet>> {
let b = ds
.mac_command_pending
.remove(&cid.to_u8().into())
.unwrap_or_default();
let out = if !b.is_empty() {
let mut mac = lrwn::MACCommandSet::from_slice(&b);
@ -44,49 +34,3 @@ pub async fn get_pending(dev_eui: &EUI64, cid: lrwn::CID) -> Result<Option<lrwn:
Ok(out)
}
pub async fn delete_pending(dev_eui: &EUI64, cid: lrwn::CID) -> Result<()> {
let key = redis_key(format!("device:{}:mac:pending:{}", dev_eui, cid.to_u8()));
() = redis::cmd("DEL")
.arg(key)
.query_async(&mut get_async_redis_conn().await?)
.await?;
info!(dev_eui = %dev_eui, cid = %cid, "Pending mac-command block deleted");
Ok(())
}
#[cfg(test)]
pub mod test {
use super::*;
use crate::test;
#[tokio::test]
async fn test_mac_command() {
let _guard = test::prepare().await;
let dev_eui = EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]);
let mac = lrwn::MACCommandSet::new(vec![lrwn::MACCommand::DevStatusReq]);
// set
set_pending(&dev_eui, lrwn::CID::DevStatusReq, &mac)
.await
.unwrap();
// get
let mac_get = get_pending(&dev_eui, lrwn::CID::DevStatusReq)
.await
.unwrap();
assert_eq!(mac, mac_get.unwrap());
// delete
delete_pending(&dev_eui, lrwn::CID::DevStatusReq)
.await
.unwrap();
let resp = get_pending(&dev_eui, lrwn::CID::DevStatusReq)
.await
.unwrap();
assert!(resp.is_none());
}
}

View File

@ -33,7 +33,7 @@ pub struct MulticastGroup {
pub group_type: String,
pub dr: i16,
pub frequency: i64,
pub class_b_ping_slot_nb_k: i16,
pub class_b_ping_slot_periodicity: i16,
pub class_c_scheduling_type: fields::MulticastGroupSchedulingType,
}
@ -64,7 +64,7 @@ impl Default for MulticastGroup {
group_type: "".into(),
dr: 0,
frequency: 0,
class_b_ping_slot_nb_k: 0,
class_b_ping_slot_periodicity: 0,
class_c_scheduling_type: fields::MulticastGroupSchedulingType::DELAY,
}
}
@ -167,7 +167,7 @@ pub async fn update(mg: MulticastGroup) -> Result<MulticastGroup, Error> {
multicast_group::group_type.eq(&mg.group_type),
multicast_group::dr.eq(&mg.dr),
multicast_group::frequency.eq(&mg.frequency),
multicast_group::class_b_ping_slot_nb_k.eq(&mg.class_b_ping_slot_nb_k),
multicast_group::class_b_ping_slot_periodicity.eq(&mg.class_b_ping_slot_periodicity),
multicast_group::class_c_scheduling_type.eq(&mg.class_c_scheduling_type),
))
.get_result(&mut get_async_db_conn().await?)
@ -429,7 +429,7 @@ pub async fn enqueue(
match mg.group_type.as_ref() {
"B" => {
// get ping nb
let ping_nb = 1 << mg.class_b_ping_slot_nb_k as usize;
let ping_nb = 1 << (7 - mg.class_b_ping_slot_periodicity) as usize;
// get max. gps epoch time.
let res: Option<i64> =
@ -746,7 +746,7 @@ pub mod test {
group_type: "C".into(),
dr: 1,
frequency: 868100000,
class_b_ping_slot_nb_k: 1,
class_b_ping_slot_periodicity: 1,
..Default::default()
})
.await
@ -759,7 +759,7 @@ pub mod test {
// update
mg.name = "test-mg-updated".into();
mg.group_type = "B".into();
mg.class_b_ping_slot_nb_k = 4;
mg.class_b_ping_slot_periodicity = 4;
mg = update(mg).await.unwrap();
let mg_get = get(&mg.id.into()).await.unwrap();
assert_eq!(mg, mg_get);
@ -884,7 +884,7 @@ pub mod test {
group_type: "C".into(),
dr: 1,
frequency: 868100000,
class_b_ping_slot_nb_k: 1,
class_b_ping_slot_periodicity: 1,
..Default::default()
})
.await
@ -942,7 +942,7 @@ pub mod test {
group_type: "C".into(),
dr: 1,
frequency: 868100000,
class_b_ping_slot_nb_k: 1,
class_b_ping_slot_periodicity: 1,
..Default::default()
})
.await
@ -1002,7 +1002,7 @@ pub mod test {
group_type: "C".into(),
dr: 1,
frequency: 868100000,
class_b_ping_slot_nb_k: 1,
class_b_ping_slot_periodicity: 1,
class_c_scheduling_type: fields::MulticastGroupSchedulingType::DELAY,
..Default::default()
})

View File

@ -153,7 +153,7 @@ diesel::table! {
supports_class_b -> Bool,
supports_class_c -> Bool,
class_b_timeout -> Int4,
class_b_ping_slot_nb_k -> Int4,
class_b_ping_slot_periodicity -> Int4,
class_b_ping_slot_dr -> Int2,
class_b_ping_slot_freq -> Int8,
class_c_timeout -> Int4,
@ -201,7 +201,7 @@ diesel::table! {
#[max_length = 20]
multicast_class_c_scheduling_type -> Varchar,
multicast_dr -> Int2,
multicast_class_b_ping_slot_nb_k -> Int2,
multicast_class_b_ping_slot_periodicity -> Int2,
multicast_frequency -> Int8,
multicast_timeout -> Int2,
multicast_session_start -> Nullable<Timestamptz>,
@ -295,7 +295,7 @@ diesel::table! {
group_type -> Bpchar,
dr -> Int2,
frequency -> Int8,
class_b_ping_slot_nb_k -> Int2,
class_b_ping_slot_periodicity -> Int2,
#[max_length = 20]
class_c_scheduling_type -> Varchar,
}

View File

@ -133,7 +133,7 @@ diesel::table! {
supports_class_b -> Bool,
supports_class_c -> Bool,
class_b_timeout -> Integer,
class_b_ping_slot_nb_k -> Integer,
class_b_ping_slot_periodicity -> Integer,
class_b_ping_slot_dr -> SmallInt,
class_b_ping_slot_freq -> BigInt,
class_c_timeout -> Integer,
@ -178,7 +178,7 @@ diesel::table! {
multicast_group_type -> Text,
multicast_class_c_scheduling_type -> Text,
multicast_dr -> SmallInt,
multicast_class_b_ping_slot_nb_k -> SmallInt,
multicast_class_b_ping_slot_periodicity -> SmallInt,
multicast_frequency -> BigInt,
multicast_timeout -> SmallInt,
multicast_session_start -> Nullable<TimestamptzSqlite>,
@ -266,7 +266,7 @@ diesel::table! {
group_type -> Text,
dr -> SmallInt,
frequency -> BigInt,
class_b_ping_slot_nb_k -> SmallInt,
class_b_ping_slot_periodicity -> SmallInt,
class_c_scheduling_type -> Text,
}
}

View File

@ -27,7 +27,7 @@ pub async fn log_uplink_for_gateways(ufl: &stream::UplinkFrameLog) -> Result<()>
phy_payload: ufl.phy_payload.clone(),
tx_info: ufl.tx_info.clone(),
rx_info: vec![rx_info.clone()],
m_type: ufl.m_type,
f_type: ufl.f_type,
dev_addr: ufl.dev_addr.clone(),
dev_eui: ufl.dev_eui.clone(),
time: ufl.time,
@ -299,7 +299,7 @@ async fn handle_stream(
seconds: t.seconds,
nanos: t.nanos,
}),
description: pl.m_type().into(),
description: pl.f_type().into(),
body: json!({
"phy_payload": phy,
"tx_info": pl.tx_info,
@ -340,7 +340,7 @@ async fn handle_stream(
seconds: t.seconds,
nanos: t.nanos,
}),
description: pl.m_type().into(),
description: pl.f_type().into(),
body: json!({
"phy_payload": phy,
"tx_info": pl.tx_info,

View File

@ -80,7 +80,7 @@ async fn test_fns_uplink() {
let data_phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -266,7 +266,7 @@ async fn test_sns_uplink() {
let mut data_phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -508,7 +508,7 @@ async fn test_sns_roaming_not_allowed() {
let mut data_phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -631,7 +631,7 @@ async fn test_sns_dev_not_found() {
let data_phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -150,7 +150,7 @@ async fn test_gateway_filtering() {
rx_info: rx_info_a.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -177,7 +177,7 @@ async fn test_gateway_filtering() {
rx_info: rx_info_b.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -292,7 +292,7 @@ async fn test_lorawan_10_errors() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -325,7 +325,7 @@ async fn test_lorawan_10_errors() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -357,7 +357,7 @@ async fn test_lorawan_10_errors() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -379,7 +379,7 @@ async fn test_lorawan_10_errors() {
rx_info: vec![rx_info.clone()],
dev_eui: "0000000000000000".into(),
dev_addr: "01020304".into(),
m_type: common::MType::UnconfirmedDataUp.into(),
f_type: common::FType::UnconfirmedDataUp.into(),
..Default::default()
}),
],
@ -489,7 +489,7 @@ async fn test_lorawan_11_errors() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -516,7 +516,7 @@ async fn test_lorawan_11_errors() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -633,7 +633,7 @@ async fn test_lorawan_10_skip_f_cnt() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -683,7 +683,7 @@ async fn test_lorawan_10_skip_f_cnt() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -821,7 +821,7 @@ async fn test_lorawan_10_device_disabled() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -949,7 +949,7 @@ async fn test_lorawan_10_uplink() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1022,7 +1022,7 @@ async fn test_lorawan_10_uplink() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1081,7 +1081,7 @@ async fn test_lorawan_10_uplink() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1154,7 +1154,7 @@ async fn test_lorawan_10_uplink() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1206,7 +1206,7 @@ async fn test_lorawan_10_uplink() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::ConfirmedDataUp,
f_type: lrwn::FType::ConfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1319,7 +1319,7 @@ async fn test_lorawan_10_uplink() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::ConfirmedDataUp,
f_type: lrwn::FType::ConfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1457,7 +1457,7 @@ async fn test_lorawan_10_uplink() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1597,7 +1597,7 @@ async fn test_lorawan_10_end_to_end_enc() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1649,7 +1649,7 @@ async fn test_lorawan_10_end_to_end_enc() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1712,7 +1712,7 @@ async fn test_lorawan_10_end_to_end_enc() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1761,7 +1761,7 @@ async fn test_lorawan_10_end_to_end_enc() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1781,7 +1781,7 @@ async fn test_lorawan_10_end_to_end_enc() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1912,7 +1912,7 @@ async fn test_lorawan_11_uplink() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -1971,7 +1971,7 @@ async fn test_lorawan_11_uplink() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2145,7 +2145,7 @@ async fn test_lorawan_10_rx_delay() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::ConfirmedDataUp,
f_type: lrwn::FType::ConfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2267,7 +2267,7 @@ async fn test_lorawan_10_rx_delay() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::ConfirmedDataUp,
f_type: lrwn::FType::ConfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2389,7 +2389,7 @@ async fn test_lorawan_10_rx_delay() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::ConfirmedDataUp,
f_type: lrwn::FType::ConfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2431,7 +2431,7 @@ async fn test_lorawan_10_rx_delay() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2455,7 +2455,7 @@ async fn test_lorawan_10_rx_delay() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2602,7 +2602,7 @@ async fn test_lorawan_10_mac_commands() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2622,7 +2622,7 @@ async fn test_lorawan_10_mac_commands() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2645,7 +2645,7 @@ async fn test_lorawan_10_mac_commands() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2701,7 +2701,7 @@ async fn test_lorawan_10_mac_commands() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2721,7 +2721,7 @@ async fn test_lorawan_10_mac_commands() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2744,7 +2744,7 @@ async fn test_lorawan_10_mac_commands() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2779,7 +2779,7 @@ async fn test_lorawan_10_mac_commands() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2803,7 +2803,7 @@ async fn test_lorawan_10_mac_commands() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2823,7 +2823,7 @@ async fn test_lorawan_10_mac_commands() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2937,7 +2937,7 @@ async fn test_lorawan_11_mac_commands() {
let mut phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -2984,7 +2984,7 @@ async fn test_lorawan_11_mac_commands() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3008,7 +3008,7 @@ async fn test_lorawan_11_mac_commands() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3141,7 +3141,7 @@ async fn test_lorawan_10_device_queue() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3161,7 +3161,7 @@ async fn test_lorawan_10_device_queue() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3181,7 +3181,7 @@ async fn test_lorawan_10_device_queue() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3228,7 +3228,7 @@ async fn test_lorawan_10_device_queue() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3248,7 +3248,7 @@ async fn test_lorawan_10_device_queue() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3270,7 +3270,7 @@ async fn test_lorawan_10_device_queue() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3311,7 +3311,7 @@ async fn test_lorawan_10_device_queue() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3331,7 +3331,7 @@ async fn test_lorawan_10_device_queue() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::ConfirmedDataDown,
f_type: lrwn::FType::ConfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3351,7 +3351,7 @@ async fn test_lorawan_10_device_queue() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::ConfirmedDataDown,
f_type: lrwn::FType::ConfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3389,7 +3389,7 @@ async fn test_lorawan_10_device_queue() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3426,7 +3426,7 @@ async fn test_lorawan_10_device_queue() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3450,7 +3450,7 @@ async fn test_lorawan_10_device_queue() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3476,7 +3476,7 @@ async fn test_lorawan_10_device_queue() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3613,7 +3613,7 @@ async fn test_lorawan_11_device_queue() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3633,7 +3633,7 @@ async fn test_lorawan_11_device_queue() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3653,7 +3653,7 @@ async fn test_lorawan_11_device_queue() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3700,7 +3700,7 @@ async fn test_lorawan_11_device_queue() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3720,7 +3720,7 @@ async fn test_lorawan_11_device_queue() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3742,7 +3742,7 @@ async fn test_lorawan_11_device_queue() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3783,7 +3783,7 @@ async fn test_lorawan_11_device_queue() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3803,7 +3803,7 @@ async fn test_lorawan_11_device_queue() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::ConfirmedDataDown,
f_type: lrwn::FType::ConfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3823,7 +3823,7 @@ async fn test_lorawan_11_device_queue() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::ConfirmedDataDown,
f_type: lrwn::FType::ConfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3861,7 +3861,7 @@ async fn test_lorawan_11_device_queue() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3898,7 +3898,7 @@ async fn test_lorawan_11_device_queue() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3924,7 +3924,7 @@ async fn test_lorawan_11_device_queue() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -3950,7 +3950,7 @@ async fn test_lorawan_11_device_queue() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4099,7 +4099,7 @@ async fn test_lorawan_10_adr() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4123,7 +4123,7 @@ async fn test_lorawan_10_adr() {
assert::downlink_phy_payloads_decoded_f_opts(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4157,7 +4157,7 @@ async fn test_lorawan_10_adr() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4203,7 +4203,7 @@ async fn test_lorawan_10_adr() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4230,38 +4230,35 @@ async fn test_lorawan_10_adr() {
name: "acknowledgement of pending adr request".into(),
dev_eui: dev.dev_eui,
device_queue_items: vec![],
before_func: Some(Box::new(move || {
let dev_eui = dev.dev_eui;
Box::pin(async move {
mac_command::set_pending(
&dev_eui,
lrwn::CID::LinkADRReq,
&lrwn::MACCommandSet::new(vec![lrwn::MACCommand::LinkADRReq(
lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 3,
ch_mask: lrwn::ChMask::new([
true, true, true, false, false, false, false, false, false,
false, false, false, false, false, false, false,
]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 1,
},
},
)]),
)
.await
.unwrap();
})
})),
before_func: None,
after_func: None,
device_session: Some(ds.clone()),
device_session: Some({
let mut ds = ds.clone();
mac_command::set_pending(
&mut ds,
&lrwn::MACCommandSet::new(vec![lrwn::MACCommand::LinkADRReq(
lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 3,
ch_mask: lrwn::ChMask::new([
true, true, true, false, false, false, false, false, false, false,
false, false, false, false, false, false,
]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 1,
},
},
)]),
)
.unwrap();
ds
}),
tx_info: tx_info.clone(),
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4298,38 +4295,35 @@ async fn test_lorawan_10_adr() {
name: "negative acknowledgement of pending adr request".into(),
dev_eui: dev.dev_eui,
device_queue_items: vec![],
before_func: Some(Box::new(move || {
let dev_eui = dev.dev_eui;
Box::pin(async move {
mac_command::set_pending(
&dev_eui,
lrwn::CID::LinkADRReq,
&lrwn::MACCommandSet::new(vec![lrwn::MACCommand::LinkADRReq(
lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 3,
ch_mask: lrwn::ChMask::new([
true, true, true, false, false, false, false, false, false,
false, false, false, false, false, false, false,
]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 1,
},
},
)]),
)
.await
.unwrap();
})
})),
before_func: None,
after_func: None,
device_session: Some(ds.clone()),
device_session: Some({
let mut ds = ds.clone();
mac_command::set_pending(
&mut ds,
&lrwn::MACCommandSet::new(vec![lrwn::MACCommand::LinkADRReq(
lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 3,
ch_mask: lrwn::ChMask::new([
true, true, true, false, false, false, false, false, false, false,
false, false, false, false, false, false,
]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 1,
},
},
)]),
)
.unwrap();
ds
}),
tx_info: tx_info.clone(),
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4373,7 +4367,7 @@ async fn test_lorawan_10_adr() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4398,7 +4392,7 @@ async fn test_lorawan_10_adr() {
assert::downlink_phy_payloads(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4418,7 +4412,7 @@ async fn test_lorawan_10_adr() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4450,7 +4444,7 @@ async fn test_lorawan_10_adr() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4470,7 +4464,7 @@ async fn test_lorawan_10_adr() {
assert::downlink_phy_payloads_decoded_f_opts(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4502,7 +4496,7 @@ async fn test_lorawan_10_adr() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4540,38 +4534,35 @@ async fn test_lorawan_10_adr() {
name: "new channel re-configuration ack-ed".into(),
dev_eui: dev.dev_eui,
device_queue_items: vec![],
before_func: Some(Box::new(move || {
let dev_eui = dev.dev_eui;
Box::pin(async move {
mac_command::set_pending(
&dev_eui,
lrwn::CID::LinkADRReq,
&lrwn::MACCommandSet::new(vec![lrwn::MACCommand::LinkADRReq(
lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 1,
ch_mask: lrwn::ChMask::new([
true, true, true, false, false, false, false, false, false,
false, false, false, false, false, false, false,
]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
},
)]),
)
.await
.unwrap();
})
})),
before_func: None,
after_func: None,
device_session: Some(ds_7chan.clone()),
device_session: Some({
let mut ds = ds_7chan.clone();
mac_command::set_pending(
&mut ds,
&lrwn::MACCommandSet::new(vec![lrwn::MACCommand::LinkADRReq(
lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 1,
ch_mask: lrwn::ChMask::new([
true, true, true, false, false, false, false, false, false, false,
false, false, false, false, false, false,
]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
},
)]),
)
.unwrap();
ds
}),
tx_info: tx_info.clone(),
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4606,38 +4597,35 @@ async fn test_lorawan_10_adr() {
name: "new channel re-configuration not ack-ed".into(),
dev_eui: dev.dev_eui,
device_queue_items: vec![],
before_func: Some(Box::new(move || {
let dev_eui = dev.dev_eui;
Box::pin(async move {
mac_command::set_pending(
&dev_eui,
lrwn::CID::LinkADRReq,
&lrwn::MACCommandSet::new(vec![lrwn::MACCommand::LinkADRReq(
lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 1,
ch_mask: lrwn::ChMask::new([
true, true, true, false, false, false, false, false, false,
false, false, false, false, false, false, false,
]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
},
)]),
)
.await
.unwrap();
})
})),
before_func: None,
after_func: None,
device_session: Some(ds_7chan.clone()),
device_session: Some({
let mut ds = ds_7chan.clone();
mac_command::set_pending(
&mut ds,
&lrwn::MACCommandSet::new(vec![lrwn::MACCommand::LinkADRReq(
lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 1,
ch_mask: lrwn::ChMask::new([
true, true, true, false, false, false, false, false, false, false,
false, false, false, false, false, false,
]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
},
)]),
)
.unwrap();
ds
}),
tx_info: tx_info.clone(),
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4678,7 +4666,7 @@ async fn test_lorawan_10_adr() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4703,7 +4691,7 @@ async fn test_lorawan_10_adr() {
assert::downlink_phy_payloads_decoded_f_opts(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4735,7 +4723,7 @@ async fn test_lorawan_10_adr() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4780,7 +4768,7 @@ async fn test_lorawan_10_adr() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4923,7 +4911,7 @@ async fn test_lorawan_10_device_status_request() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4942,7 +4930,7 @@ async fn test_lorawan_10_device_status_request() {
assert::downlink_phy_payloads_decoded_f_opts(vec![
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -4965,7 +4953,7 @@ async fn test_lorawan_10_device_status_request() {
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -5000,7 +4988,7 @@ async fn test_lorawan_10_device_status_request() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -5031,7 +5019,7 @@ async fn test_lorawan_10_device_status_request() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -5193,7 +5181,7 @@ async fn test_lorawan_11_receive_window_selection() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -5263,7 +5251,7 @@ async fn test_lorawan_11_receive_window_selection() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -5333,7 +5321,7 @@ async fn test_lorawan_11_receive_window_selection() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -5432,7 +5420,7 @@ async fn test_lorawan_11_receive_window_selection() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -133,7 +133,7 @@ async fn test_uplink() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -168,7 +168,7 @@ async fn test_uplink() {
rx_info: rx_info.clone(),
phy_payload: lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -86,7 +86,7 @@ async fn test_multicast() {
group_type: "C".into(),
dr: 3,
frequency: 868300000,
class_b_ping_slot_nb_k: 0,
class_b_ping_slot_periodicity: 0,
..Default::default()
})
.await

View File

@ -85,7 +85,7 @@ async fn test_js() {
let phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinRequest,
f_type: lrwn::FType::JoinRequest,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {
@ -98,7 +98,7 @@ async fn test_js() {
let phy_ja = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinAccept,
f_type: lrwn::FType::JoinAccept,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinAccept(lrwn::JoinAcceptPayload {

View File

@ -84,7 +84,7 @@ async fn test_fns() {
let mut jr_phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinRequest,
f_type: lrwn::FType::JoinRequest,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {
@ -319,7 +319,7 @@ async fn test_sns() {
let mut jr_phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinRequest,
f_type: lrwn::FType::JoinRequest,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {
@ -504,7 +504,7 @@ async fn test_sns_roaming_not_allowed() {
let mut jr_phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinRequest,
f_type: lrwn::FType::JoinRequest,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {

View File

@ -134,7 +134,7 @@ async fn test_gateway_filtering() {
let mut jr_pl = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinRequest,
f_type: lrwn::FType::JoinRequest,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {
@ -291,7 +291,7 @@ async fn test_lorawan_10() {
let mut jr_pl = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinRequest,
f_type: lrwn::FType::JoinRequest,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {
@ -305,7 +305,7 @@ async fn test_lorawan_10() {
let mut ja_pl = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinAccept,
f_type: lrwn::FType::JoinAccept,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinAccept(lrwn::JoinAcceptPayload {
@ -334,7 +334,7 @@ async fn test_lorawan_10() {
let mut ja_cflist_pl = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinAccept,
f_type: lrwn::FType::JoinAccept,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinAccept(lrwn::JoinAcceptPayload {
@ -561,7 +561,7 @@ async fn test_lorawan_10() {
tx_info: Some(tx_info.clone()),
rx_info: vec![rx_info.clone()],
phy_payload_byte_count: 23,
message_type: common::MType::JoinRequest.into(),
frame_type: common::FType::JoinRequest.into(),
..Default::default()
}),
],
@ -942,7 +942,7 @@ async fn test_lorawan_11() {
let mut jr_pl = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinRequest,
f_type: lrwn::FType::JoinRequest,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {
@ -956,7 +956,7 @@ async fn test_lorawan_11() {
let mut ja_pl = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinAccept,
f_type: lrwn::FType::JoinAccept,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinAccept(lrwn::JoinAcceptPayload {

View File

@ -164,7 +164,7 @@ async fn test_lorawan_10() {
let mut phy_relay_ed_unconfirmed_up = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -196,7 +196,7 @@ async fn test_lorawan_10() {
let mut phy_relay_ed_confirmed_up = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::ConfirmedDataUp,
f_type: lrwn::FType::ConfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -228,7 +228,7 @@ async fn test_lorawan_10() {
let mut phy_relay_unconfirmed_up = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -267,7 +267,7 @@ async fn test_lorawan_10() {
let mut phy_relay_unconfirmed_up_adr_ack_req = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -310,7 +310,7 @@ async fn test_lorawan_10() {
let mut phy_relay_confirmed_up = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -349,7 +349,7 @@ async fn test_lorawan_10() {
let mut phy_relay_ed_unconfirmed_down_ack = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -378,7 +378,7 @@ async fn test_lorawan_10() {
let mut phy_relay_unconfirmed_down_ack = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -413,7 +413,7 @@ async fn test_lorawan_10() {
let mut phy_relay_unconfirmed_down_empty = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -138,7 +138,7 @@ async fn test_lorawan_10() {
let mut jr_pl = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinRequest,
f_type: lrwn::FType::JoinRequest,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {
@ -152,7 +152,7 @@ async fn test_lorawan_10() {
let mut ja_pl = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinAccept,
f_type: lrwn::FType::JoinAccept,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinAccept(lrwn::JoinAcceptPayload {
@ -181,7 +181,7 @@ async fn test_lorawan_10() {
let mut phy_relay_jr = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -233,7 +233,7 @@ async fn test_lorawan_10() {
let mut phy_relay_ja = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataDown,
f_type: lrwn::FType::UnconfirmedDataDown,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {

View File

@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::str::FromStr;
use anyhow::{Context, Result};
use chrono::{DateTime, Duration, Local, Utc};
use chrono::{DateTime, Local, Utc};
use tracing::{debug, error, info, span, trace, warn, Instrument, Level};
use super::error::Error;
@ -126,7 +126,6 @@ impl Data {
ctx.set_device_info()?;
ctx.set_device_gateway_rx_info()?;
ctx.handle_retransmission_reset().await?;
ctx.set_scheduler_run_after().await?;
ctx.decrypt_f_opts_mac_commands()?;
ctx.decrypt_frm_payload()?;
ctx.log_uplink_frame_set().await?;
@ -522,36 +521,6 @@ impl Data {
Err(Error::Abort)
}
// For Class-B and Class-C devices, set the scheduler_run_after timestamp to avoid collisions with
// the Class-A downlink and Class-B/C scheduler.
async fn set_scheduler_run_after(&mut self) -> Result<()> {
let dev = self.device.as_mut().unwrap();
let conf = config::get();
if dev.enabled_class == DeviceClass::B || dev.enabled_class == DeviceClass::C {
trace!("Setting scheduler_run_after for device");
let scheduler_run_after =
Utc::now() + Duration::from_std(conf.network.scheduler.class_a_lock_duration)?;
// Only set the new scheduler_run_after if it is currently None
// or when the current value is before the calculated scheduler_run_after.
if dev.scheduler_run_after.is_none()
|| scheduler_run_after > dev.scheduler_run_after.unwrap()
{
*dev = device::partial_update(
dev.dev_eui,
&device::DeviceChangeset {
scheduler_run_after: Some(Some(scheduler_run_after)),
..Default::default()
},
)
.await?;
}
}
Ok(())
}
async fn filter_rx_info_by_tenant(&mut self) -> Result<()> {
trace!("Filtering rx_info by tenant_id");
@ -747,7 +716,7 @@ impl Data {
0
}
} as u32,
message_type: self.phy_payload.mhdr.m_type.to_proto().into(),
frame_type: self.phy_payload.mhdr.f_type.to_proto().into(),
};
stream::meta::log_uplink(&um).await?;
@ -938,7 +907,7 @@ impl Data {
dr: self.uplink_frame_set.dr as u32,
f_cnt: self.f_cnt_up_full,
f_port: mac.f_port.unwrap_or(0) as u32,
confirmed: self.phy_payload.mhdr.m_type == lrwn::MType::ConfirmedDataUp,
confirmed: self.phy_payload.mhdr.f_type == lrwn::FType::ConfirmedDataUp,
data: match &mac.frm_payload {
Some(lrwn::FRMPayload::Raw(b)) => b.clone(),
_ => Vec::new(),
@ -1319,7 +1288,7 @@ impl Data {
self.device_profile.as_ref().cloned().unwrap(),
self.device.as_ref().cloned().unwrap(),
pl.fhdr.f_ctrl.adr_ack_req || self.must_send_downlink,
self.phy_payload.mhdr.m_type == lrwn::MType::ConfirmedDataUp,
self.phy_payload.mhdr.f_type == lrwn::FType::ConfirmedDataUp,
self.downlink_mac_commands.clone(),
)
.await?;
@ -1362,7 +1331,7 @@ impl Data {
self.device_profile.as_ref().cloned().unwrap(),
self.device.as_ref().cloned().unwrap(),
pl.fhdr.f_ctrl.adr_ack_req || self.must_send_downlink,
self.phy_payload.mhdr.m_type == lrwn::MType::ConfirmedDataUp,
self.phy_payload.mhdr.f_type == lrwn::FType::ConfirmedDataUp,
self.downlink_mac_commands.clone(),
)
.await?;
@ -1376,29 +1345,29 @@ impl Data {
if let lrwn::Payload::MACPayload(relay_pl) = &self.phy_payload.payload {
if let Some(lrwn::FRMPayload::ForwardUplinkReq(pl)) = &relay_pl.frm_payload {
match pl.payload.mhdr.m_type {
lrwn::MType::JoinRequest => {
match pl.payload.mhdr.f_type {
lrwn::FType::JoinRequest => {
super::join::JoinRequest::handle_relayed(
super::RelayContext {
req: pl.clone(),
device: self.device.as_ref().unwrap().clone(),
device_profile: self.device_profile.as_ref().unwrap().clone(),
must_ack: self.phy_payload.mhdr.m_type
== lrwn::MType::ConfirmedDataUp,
must_ack: self.phy_payload.mhdr.f_type
== lrwn::FType::ConfirmedDataUp,
must_send_downlink: relay_pl.fhdr.f_ctrl.adr_ack_req,
},
self.uplink_frame_set.clone(),
)
.await
}
lrwn::MType::UnconfirmedDataUp | lrwn::MType::ConfirmedDataUp => {
lrwn::FType::UnconfirmedDataUp | lrwn::FType::ConfirmedDataUp => {
Data::handle_relayed(
super::RelayContext {
req: pl.clone(),
device: self.device.as_ref().unwrap().clone(),
device_profile: self.device_profile.as_ref().unwrap().clone(),
must_ack: self.phy_payload.mhdr.m_type
== lrwn::MType::ConfirmedDataUp,
must_ack: self.phy_payload.mhdr.f_type
== lrwn::FType::ConfirmedDataUp,
must_send_downlink: relay_pl.fhdr.f_ctrl.adr_ack_req,
},
self.device_gateway_rx_info.as_ref().unwrap().clone(),
@ -1408,8 +1377,8 @@ impl Data {
}
_ => {
return Err(anyhow!(
"Handling ForwardUplinkReq for MType {} supported",
pl.payload.mhdr.m_type
"Handling ForwardUplinkReq for FType {} supported",
pl.payload.mhdr.f_type
));
}
}

View File

@ -6,7 +6,7 @@ use chrono::{DateTime, Local, Utc};
use tracing::{error, info, span, trace, warn, Instrument, Level};
use lrwn::{
keys, AES128Key, CFList, DLSettings, JoinAcceptPayload, JoinRequestPayload, JoinType, MType,
keys, AES128Key, CFList, DLSettings, FType, JoinAcceptPayload, JoinRequestPayload, JoinType,
Major, Payload, PhyPayload, MHDR,
};
@ -636,7 +636,7 @@ impl JoinRequest {
let mut phy = PhyPayload {
mhdr: MHDR {
m_type: MType::JoinAccept,
f_type: FType::JoinAccept,
major: Major::LoRaWANR1,
},
payload: Payload::JoinAccept(JoinAcceptPayload {
@ -757,7 +757,7 @@ impl JoinRequest {
dev_eui: self.device.as_ref().unwrap().dev_eui.to_string(),
tx_info: Some(self.uplink_frame_set.tx_info.clone()),
rx_info: self.uplink_frame_set.rx_info_set.clone(),
message_type: common::MType::JoinRequest.into(),
frame_type: common::FType::JoinRequest.into(),
phy_payload_byte_count: self.uplink_frame_set.phy_payload.to_vec()?.len() as u32,
..Default::default()
};

View File

@ -431,7 +431,7 @@ impl JoinRequest {
let mut phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinAccept,
f_type: lrwn::FType::JoinAccept,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinAccept(lrwn::JoinAcceptPayload {
@ -552,7 +552,7 @@ impl JoinRequest {
dev_eui: self.device.as_ref().unwrap().dev_eui.to_string(),
tx_info: Some(self.uplink_frame_set.tx_info.clone()),
rx_info: self.uplink_frame_set.rx_info_set.clone(),
message_type: common::MType::JoinRequest.into(),
frame_type: common::FType::JoinRequest.into(),
phy_payload_byte_count: self.uplink_frame_set.phy_payload.to_vec()?.len() as u32,
..Default::default()
};

View File

@ -14,14 +14,15 @@ use crate::storage::{
};
use lrwn::EUI64;
pub struct MeshHeartbeat {
pub struct Mesh {
gateway_id: EUI64,
relay_id: RelayId,
mesh_stats: gw::MeshHeartbeat,
time: DateTime<Utc>,
mesh_event: gw::MeshEvent,
}
impl MeshHeartbeat {
pub async fn handle(s: gw::MeshHeartbeat) {
impl Mesh {
pub async fn handle(s: gw::MeshEvent) {
let gateway_id = match EUI64::from_str(&s.gateway_id) {
Ok(v) => v,
Err(e) => {
@ -38,9 +39,9 @@ impl MeshHeartbeat {
}
};
let span = span!(Level::INFO, "mesh_stats", gateway_id = %gateway_id, relay_id = %relay_id);
let span = span!(Level::INFO, "mesh", gateway_id = %gateway_id, relay_id = %relay_id);
if let Err(e) = MeshHeartbeat::_handle(gateway_id, relay_id, s)
if let Err(e) = Mesh::_handle(gateway_id, relay_id, s)
.instrument(span)
.await
{
@ -48,52 +49,61 @@ impl MeshHeartbeat {
Some(Error::NotFound(_)) => {
let conf = config::get();
if !conf.gateway.allow_unknown_gateways {
error!(error = %e.full(), "Handle mesh-stats error");
error!(error = %e.full(), "Handle mesh error");
}
}
Some(_) | None => {
error!(error = %e.full(), "Handle mesh-stats error");
error!(error = %e.full(), "Handle mesh error");
}
}
}
}
async fn _handle(gateway_id: EUI64, relay_id: RelayId, s: gw::MeshHeartbeat) -> Result<()> {
let mut ctx = MeshHeartbeat {
async fn _handle(gateway_id: EUI64, relay_id: RelayId, s: gw::MeshEvent) -> Result<()> {
let ctx = Mesh {
gateway_id,
relay_id,
mesh_stats: s,
time: s
.time
.ok_or_else(|| anyhow!("Time field is empty"))?
.try_into()
.map_err(|e| anyhow!("Covert time error: {}", e))?,
mesh_event: s,
};
ctx.update_or_create_relay_gateway().await?;
ctx.handle_events().await?;
Ok(())
}
async fn update_or_create_relay_gateway(&mut self) -> Result<()> {
trace!("Getting Border Gateway");
let border_gw = gateway::get(&self.gateway_id).await?;
async fn handle_events(&self) -> Result<()> {
trace!("Handling mesh events");
let ts: DateTime<Utc> = match &self.mesh_stats.time {
Some(v) => (*v)
.try_into()
.map_err(|e| anyhow!("Convert time error: {}", e))?,
None => {
warn!("Stats message does not have time field set");
return Ok(());
for event in &self.mesh_event.events {
match &event.event {
Some(gw::mesh_event_item::Event::Proprietary(_)) | None => continue,
Some(gw::mesh_event_item::Event::Heartbeat(v)) => self._handle_heartbeat(v).await?,
}
};
}
Ok(())
}
async fn _handle_heartbeat(&self, _pl: &gw::MeshEventHeartbeat) -> Result<()> {
trace!("Handling heartbeat event");
let border_gw = gateway::get(&self.gateway_id).await?;
match gateway::get_relay_gateway(border_gw.tenant_id.into(), self.relay_id).await {
Ok(mut v) => {
if let Some(last_seen_at) = v.last_seen_at {
if last_seen_at > ts {
warn!("Time is less than last seen timestamp, ignoring stats");
if last_seen_at > self.time {
warn!("Time is less than last seen timestamp, ignoring heartbeat");
return Ok(());
}
}
v.last_seen_at = Some(ts);
v.last_seen_at = Some(self.time);
v.region_config_id = border_gw
.properties
.get("region_config_id")
@ -106,7 +116,7 @@ impl MeshHeartbeat {
tenant_id: border_gw.tenant_id,
relay_id: self.relay_id,
name: self.relay_id.to_string(),
last_seen_at: Some(ts),
last_seen_at: Some(self.time),
..Default::default()
})
.await?;

View File

@ -24,7 +24,7 @@ use crate::storage::{
use crate::stream;
use chirpstack_api::{common, gw, stream as stream_pb};
use lrwn::region::CommonName;
use lrwn::{ForwardUplinkReq, MType, PhyPayload, EUI64};
use lrwn::{FType, ForwardUplinkReq, PhyPayload, EUI64};
mod data;
mod data_fns;
@ -39,7 +39,7 @@ pub mod stats;
#[derive(Clone, Hash, PartialEq, Eq, EncodeLabelSet, Debug)]
struct UplinkLabels {
m_type: String,
f_type: String,
}
static UPLINK_COUNTER: LazyLock<Family<UplinkLabels, Counter>> = LazyLock::new(|| {
@ -105,16 +105,16 @@ impl TryFrom<&UplinkFrameSet> for stream_pb::UplinkFrameLog {
phy_payload: ufs.phy_payload.to_vec()?,
tx_info: Some(ufs.tx_info.clone()),
rx_info: ufs.rx_info_set.clone(),
m_type: match ufs.phy_payload.mhdr.m_type {
lrwn::MType::JoinRequest => common::MType::JoinRequest,
lrwn::MType::RejoinRequest => common::MType::RejoinRequest,
lrwn::MType::UnconfirmedDataUp => common::MType::UnconfirmedDataUp,
lrwn::MType::ConfirmedDataUp => common::MType::ConfirmedDataUp,
lrwn::MType::Proprietary => common::MType::Proprietary,
f_type: match ufs.phy_payload.mhdr.f_type {
lrwn::FType::JoinRequest => common::FType::JoinRequest,
lrwn::FType::RejoinRequest => common::FType::RejoinRequest,
lrwn::FType::UnconfirmedDataUp => common::FType::UnconfirmedDataUp,
lrwn::FType::ConfirmedDataUp => common::FType::ConfirmedDataUp,
lrwn::FType::Proprietary => common::FType::Proprietary,
_ => {
return Err(anyhow!(
"Unexpected m_type: {}",
ufs.phy_payload.mhdr.m_type
"Unexpected f_type: {}",
ufs.phy_payload.mhdr.f_type
));
}
}
@ -324,7 +324,7 @@ pub async fn handle_uplink(
UPLINK_COUNTER
.get_or_create(&UplinkLabels {
m_type: uplink.phy_payload.mhdr.m_type.to_string(),
f_type: uplink.phy_payload.mhdr.f_type.to_string(),
})
.inc();
@ -336,7 +336,7 @@ pub async fn handle_uplink(
)?;
info!(
m_type = %uplink.phy_payload.mhdr.m_type,
f_type = %uplink.phy_payload.mhdr.f_type,
"Uplink received"
);
@ -351,13 +351,13 @@ pub async fn handle_uplink(
.await
.context("Log uplink for gateways")?;
match uplink.phy_payload.mhdr.m_type {
MType::JoinRequest => join::JoinRequest::handle(uplink).await,
MType::UnconfirmedDataUp | MType::ConfirmedDataUp => data::Data::handle(uplink).await,
match uplink.phy_payload.mhdr.f_type {
FType::JoinRequest => join::JoinRequest::handle(uplink).await,
FType::UnconfirmedDataUp | FType::ConfirmedDataUp => data::Data::handle(uplink).await,
_ => {
return Err(anyhow!(
"Unexpected m_type: {}",
uplink.phy_payload.mhdr.m_type
"Unexpected f_type: {}",
uplink.phy_payload.mhdr.f_type
))
}
}

View File

@ -6,11 +6,11 @@ RUN apt-get update && \
libprotobuf-dev
ENV MUSL_PREFIX=aarch64-linux-musl
ENV SQLITE_VERSION=3460000
ENV SQLITE_VERSION=3490100
RUN echo "Building SQLite" && \
cd /tmp && \
curl -fLO "https://sqlite.org/2024/sqlite-autoconf-$SQLITE_VERSION.tar.gz" && \
curl -fLO "https://sqlite.org/2025/sqlite-autoconf-$SQLITE_VERSION.tar.gz" && \
tar xvzf "sqlite-autoconf-$SQLITE_VERSION.tar.gz" && cd "sqlite-autoconf-$SQLITE_VERSION" && \
env CC=$MUSL_PREFIX-gcc ./configure --host=aarch64-linux --enable-static --prefix=/usr/local/$MUSL_PREFIX-target && \
make && make install && \

View File

@ -6,11 +6,11 @@ RUN apt-get update && \
libprotobuf-dev
ENV MUSL_PREFIX=arm-linux-musleabihf
ENV SQLITE_VERSION=3460000
ENV SQLITE_VERSION=3490100
RUN echo "Building SQLite" && \
cd /tmp && \
curl -fLO "https://sqlite.org/2024/sqlite-autoconf-$SQLITE_VERSION.tar.gz" && \
curl -fLO "https://sqlite.org/2025/sqlite-autoconf-$SQLITE_VERSION.tar.gz" && \
tar xvzf "sqlite-autoconf-$SQLITE_VERSION.tar.gz" && cd "sqlite-autoconf-$SQLITE_VERSION" && \
env CC=$MUSL_PREFIX-gcc ./configure --host=arm-linux --enable-static --prefix=/usr/local/$MUSL_PREFIX-target && \
make && make install && \

View File

@ -6,11 +6,11 @@ RUN apt-get update && \
libprotobuf-dev
ENV MUSL_PREFIX=x86_64-linux-musl
ENV SQLITE_VERSION=3460000
ENV SQLITE_VERSION=3490100
RUN echo "Building SQLite" && \
cd /tmp && \
curl -fLO "https://sqlite.org/2024/sqlite-autoconf-$SQLITE_VERSION.tar.gz" && \
curl -fLO "https://sqlite.org/2025/sqlite-autoconf-$SQLITE_VERSION.tar.gz" && \
tar xvzf "sqlite-autoconf-$SQLITE_VERSION.tar.gz" && cd "sqlite-autoconf-$SQLITE_VERSION" && \
env CC=$MUSL_PREFIX-gcc ./configure --enable-static --prefix=/usr/local/$MUSL_PREFIX-target && \
make && make install && \

View File

@ -3,7 +3,7 @@
description = "Library for filtering LoRaWAN payloads on DevAddr and JoinEUIs prefixes"
homepage = "https://www.chirpstack.io/"
license = "MIT"
version = "4.12.0"
version = "4.13.0-test.1"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
repository = "https://github.com/chirpstack/chirpstack"

View File

@ -30,9 +30,9 @@ pub fn matches(phy_payload: &[u8], config: &Filters) -> bool {
}
let mhdr = phy_payload[0];
let m_type = mhdr >> 5;
let f_type = mhdr >> 5;
let dev_addr: Option<[u8; 4]> = match m_type {
let dev_addr: Option<[u8; 4]> = match f_type {
// DataUp
0x02 | 0x04 => {
// MHDR + DevAddr
@ -48,7 +48,7 @@ pub fn matches(phy_payload: &[u8], config: &Filters) -> bool {
_ => None,
};
let join_eui: Option<[u8; 8]> = match m_type {
let join_eui: Option<[u8; 8]> = match f_type {
// JoinRequest
0x00 => {
// MHDR + JoinEUI + DevEUI
@ -362,7 +362,7 @@ mod test {
println!("> {}", test.name);
let phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::UnconfirmedDataUp,
f_type: lrwn::FType::UnconfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -382,7 +382,7 @@ mod test {
let phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::ConfirmedDataUp,
f_type: lrwn::FType::ConfirmedDataUp,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::MACPayload(lrwn::MACPayload {
@ -457,7 +457,7 @@ mod test {
println!("> {}", test.name);
let phy = lrwn::PhyPayload {
mhdr: lrwn::MHDR {
m_type: lrwn::MType::JoinRequest,
f_type: lrwn::FType::JoinRequest,
major: lrwn::Major::LoRaWANR1,
},
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {

View File

@ -3,7 +3,7 @@
description = "Library for encoding / decoding LoRaWAN frames."
homepage = "https://www.chirpstack.io"
license = "MIT"
version = "4.12.0"
version = "4.13.0-test.1"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2018"
repository = "https://github.com/chirpstack/chirpstack"

View File

@ -402,6 +402,15 @@ impl MACCommandSet {
MACCommandSet(macs)
}
// This reads the CID from the first mac-command in the set. It is assumed
// that all mac-commands in the set share the same CID.
pub fn cid(&self) -> Result<CID> {
self.0
.first()
.map(|v| v.cid())
.ok_or_else(|| anyhow!("Set is empty"))
}
pub fn size(&self) -> Result<usize> {
let b = self.to_vec()?;
Ok(b.len())

View File

@ -6,7 +6,7 @@ use serde::Serialize;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum MType {
pub enum FType {
JoinRequest,
JoinAccept,
UnconfirmedDataUp,
@ -17,7 +17,7 @@ pub enum MType {
Proprietary,
}
impl fmt::Display for MType {
impl fmt::Display for FType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
@ -32,22 +32,22 @@ pub enum Major {
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct MHDR {
pub m_type: MType,
pub f_type: FType,
pub major: Major,
}
impl MHDR {
pub fn from_le_bytes(b: [u8; 1]) -> Result<Self> {
Ok(MHDR {
m_type: match b[0] >> 5 {
0x00 => MType::JoinRequest,
0x01 => MType::JoinAccept,
0x02 => MType::UnconfirmedDataUp,
0x03 => MType::UnconfirmedDataDown,
0x04 => MType::ConfirmedDataUp,
0x05 => MType::ConfirmedDataDown,
0x06 => MType::RejoinRequest,
0x07 => MType::Proprietary,
f_type: match b[0] >> 5 {
0x00 => FType::JoinRequest,
0x01 => FType::JoinAccept,
0x02 => FType::UnconfirmedDataUp,
0x03 => FType::UnconfirmedDataDown,
0x04 => FType::ConfirmedDataUp,
0x05 => FType::ConfirmedDataDown,
0x06 => FType::RejoinRequest,
0x07 => FType::Proprietary,
_ => return Err(anyhow!("unexpected mtype")),
},
major: match b[0] & 0x03 {
@ -58,15 +58,15 @@ impl MHDR {
}
pub fn to_le_bytes(&self) -> [u8; 1] {
let mut mhdr = match self.m_type {
MType::JoinRequest => 0x00,
MType::JoinAccept => 0x01,
MType::UnconfirmedDataUp => 0x02,
MType::UnconfirmedDataDown => 0x03,
MType::ConfirmedDataUp => 0x04,
MType::ConfirmedDataDown => 0x05,
MType::RejoinRequest => 0x06,
MType::Proprietary => 0x07,
let mut mhdr = match self.f_type {
FType::JoinRequest => 0x00,
FType::JoinAccept => 0x01,
FType::UnconfirmedDataUp => 0x02,
FType::UnconfirmedDataDown => 0x03,
FType::ConfirmedDataUp => 0x04,
FType::ConfirmedDataDown => 0x05,
FType::RejoinRequest => 0x06,
FType::Proprietary => 0x07,
};
mhdr = (mhdr << 5)
@ -85,7 +85,7 @@ mod tests {
#[test]
fn test_to_le_bytes() {
let mhdr = MHDR {
m_type: MType::Proprietary,
f_type: FType::Proprietary,
major: Major::LoRaWANR1,
};
@ -98,7 +98,7 @@ mod tests {
assert_eq!(
mhdr,
MHDR {
m_type: MType::Proprietary,
f_type: FType::Proprietary,
major: Major::LoRaWANR1,
}
);

View File

@ -9,7 +9,7 @@ use crate::eui64::EUI64;
use crate::fhdr::FCtrl;
use crate::fhdr::FHDR;
use crate::maccommand::MACCommandSet;
use crate::mhdr::MType;
use crate::mhdr::FType;
use crate::netid::NetID;
use crate::relay::{ForwardDownlinkReq, ForwardUplinkReq};
@ -50,15 +50,15 @@ pub enum JoinType {
}
impl Payload {
pub fn from_slice(m_type: MType, b: &[u8]) -> Result<Self> {
Ok(match m_type {
MType::JoinRequest => Payload::JoinRequest(JoinRequestPayload::from_slice(b)?),
MType::JoinAccept => Payload::Raw(b.to_vec()), // the join-accept is encrypted
MType::UnconfirmedDataUp
| MType::ConfirmedDataUp
| MType::UnconfirmedDataDown
| MType::ConfirmedDataDown => Payload::MACPayload(MACPayload::from_slice(b)?),
MType::RejoinRequest => {
pub fn from_slice(f_type: FType, b: &[u8]) -> Result<Self> {
Ok(match f_type {
FType::JoinRequest => Payload::JoinRequest(JoinRequestPayload::from_slice(b)?),
FType::JoinAccept => Payload::Raw(b.to_vec()), // the join-accept is encrypted
FType::UnconfirmedDataUp
| FType::ConfirmedDataUp
| FType::UnconfirmedDataDown
| FType::ConfirmedDataDown => Payload::MACPayload(MACPayload::from_slice(b)?),
FType::RejoinRequest => {
if b.is_empty() {
return Err(anyhow!("RejoinRequest payload is empty"));
}
@ -73,7 +73,7 @@ impl Payload {
}
}
}
MType::Proprietary => Payload::Raw(b.to_vec()),
FType::Proprietary => Payload::Raw(b.to_vec()),
})
}
@ -453,7 +453,7 @@ mod tests {
assert_eq!(tst.bytes, tst.pl.to_vec().unwrap());
assert_eq!(
tst.pl,
Payload::from_slice(MType::JoinRequest, &tst.bytes).unwrap()
Payload::from_slice(FType::JoinRequest, &tst.bytes).unwrap()
);
}
}
@ -464,7 +464,7 @@ mod tests {
// before it can be decoded
assert_eq!(
Payload::Raw(vec![0x01, 0x02, 0x03]),
Payload::from_slice(MType::JoinAccept, &[0x01, 0x02, 0x03]).unwrap()
Payload::from_slice(FType::JoinAccept, &[0x01, 0x02, 0x03]).unwrap()
);
// test decoding the (decrypted) join-accept payload
@ -611,7 +611,7 @@ mod tests {
assert_eq!(tst.bytes, tst.pl.to_vec().unwrap());
assert_eq!(
tst.pl,
Payload::from_slice(MType::UnconfirmedDataUp, &tst.bytes).unwrap()
Payload::from_slice(FType::UnconfirmedDataUp, &tst.bytes).unwrap()
);
}
}
@ -661,7 +661,7 @@ mod tests {
assert_eq!(tst.bytes, tst.pl.to_vec().unwrap());
assert_eq!(
tst.pl,
Payload::from_slice(MType::RejoinRequest, &tst.bytes).unwrap()
Payload::from_slice(FType::RejoinRequest, &tst.bytes).unwrap()
);
}
}
@ -677,7 +677,7 @@ mod tests {
assert_eq!(tst.bytes, tst.pl.to_vec().unwrap());
assert_eq!(
tst.pl,
Payload::from_slice(MType::Proprietary, &tst.bytes).unwrap()
Payload::from_slice(FType::Proprietary, &tst.bytes).unwrap()
);
}
}

View File

@ -10,7 +10,7 @@ use cmac::{Cmac, Mac};
use serde::Serialize;
use super::maccommand::{MACCommand, MACCommandSet};
use super::mhdr::{MType, MHDR};
use super::mhdr::{FType, MHDR};
use super::payload::{FRMPayload, MACPayload, Payload};
#[cfg(feature = "crypto")]
use super::{
@ -40,7 +40,7 @@ pub enum MACVersion {
///
/// let mut phy = PhyPayload {
/// mhdr: MHDR {
/// m_type: MType::JoinRequest,
/// f_type: FType::JoinRequest,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::JoinRequest(JoinRequestPayload {
@ -73,7 +73,7 @@ pub enum MACVersion {
///
/// let mut phy = PhyPayload {
/// mhdr: MHDR {
/// m_type: MType::JoinAccept,
/// f_type: FType::JoinAccept,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::JoinAccept(JoinAcceptPayload {
@ -105,7 +105,7 @@ pub enum MACVersion {
///
/// assert_eq!(PhyPayload {
/// mhdr: MHDR {
/// m_type: MType::JoinAccept,
/// f_type: FType::JoinAccept,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::JoinAccept(JoinAcceptPayload {
@ -135,7 +135,7 @@ pub enum MACVersion {
///
/// let mut phy = PhyPayload {
/// mhdr: MHDR {
/// m_type: MType::JoinAccept,
/// f_type: FType::JoinAccept,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::JoinAccept(JoinAcceptPayload {
@ -167,7 +167,7 @@ pub enum MACVersion {
///
/// assert_eq!(PhyPayload {
/// mhdr: MHDR {
/// m_type: MType::JoinAccept,
/// f_type: FType::JoinAccept,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::JoinAccept(JoinAcceptPayload {
@ -196,7 +196,7 @@ pub enum MACVersion {
///
/// let mut phy = PhyPayload {
/// mhdr: MHDR {
/// m_type: MType::ConfirmedDataUp,
/// f_type: FType::ConfirmedDataUp,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::MACPayload(MACPayload{
@ -250,7 +250,7 @@ pub enum MACVersion {
///
/// let mut phy = PhyPayload {
/// mhdr: MHDR{
/// m_type: MType::UnconfirmedDataDown,
/// f_type: FType::UnconfirmedDataDown,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::MACPayload(MACPayload{
@ -309,7 +309,7 @@ pub enum MACVersion {
///
/// let phy = PhyPayload {
/// mhdr: MHDR {
/// m_type: MType::Proprietary,
/// f_type: FType::Proprietary,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::Raw(vec![0x01, 0x02, 0x03]),
@ -332,7 +332,7 @@ pub enum MACVersion {
/// let ed_app_key = AES128Key::from_str("01020304050607080102030405060708").unwrap();
/// let mut ed_phy = PhyPayload {
/// mhdr: MHDR {
/// m_type: MType::JoinRequest,
/// f_type: FType::JoinRequest,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::JoinRequest(JoinRequestPayload {
@ -349,7 +349,7 @@ pub enum MACVersion {
/// let relay_nwk_s_key = AES128Key::from_str("08070605040302010807060504030201").unwrap();
/// let mut relay_phy = PhyPayload {
/// mhdr: MHDR {
/// m_type: MType::UnconfirmedDataUp,
/// f_type: FType::UnconfirmedDataUp,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::MACPayload(MACPayload {
@ -384,7 +384,7 @@ pub enum MACVersion {
/// relay_phy_decoded.decrypt_frm_payload(&relay_nwk_s_key).unwrap();
/// assert_eq!(PhyPayload{
/// mhdr: MHDR {
/// m_type: MType::UnconfirmedDataUp,
/// f_type: FType::UnconfirmedDataUp,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::MACPayload(MACPayload {
@ -420,7 +420,7 @@ pub enum MACVersion {
/// let ed_dev_nonce = 258;
/// let mut ed_phy = PhyPayload {
/// mhdr: MHDR {
/// m_type: MType::JoinAccept,
/// f_type: FType::JoinAccept,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::JoinAccept(JoinAcceptPayload {
@ -445,7 +445,7 @@ pub enum MACVersion {
/// let relay_nwk_s_key = AES128Key::from_str("08070605040302010807060504030201").unwrap();
/// let mut relay_phy = PhyPayload {
/// mhdr: MHDR {
/// m_type: MType::UnconfirmedDataDown,
/// f_type: FType::UnconfirmedDataDown,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::MACPayload(MACPayload {
@ -473,7 +473,7 @@ pub enum MACVersion {
/// relay_phy_decoded.decrypt_frm_payload(&relay_nwk_s_key).unwrap();
/// assert_eq!(PhyPayload {
/// mhdr: MHDR {
/// m_type: MType::UnconfirmedDataDown,
/// f_type: FType::UnconfirmedDataDown,
/// major: Major::LoRaWANR1,
/// },
/// payload: Payload::MACPayload(MACPayload {
@ -526,10 +526,10 @@ impl PhyPayload {
MHDR::from_le_bytes(mhdr)?
};
if mhdr.m_type == MType::Proprietary {
if mhdr.f_type == FType::Proprietary {
return Ok(PhyPayload {
mhdr,
payload: Payload::from_slice(MType::Proprietary, &b[1..])?,
payload: Payload::from_slice(FType::Proprietary, &b[1..])?,
mic: None,
});
}
@ -541,13 +541,13 @@ impl PhyPayload {
));
}
let m_type = mhdr.m_type;
let f_type = mhdr.f_type;
let mut mic: [u8; 4] = [0; 4];
mic.clone_from_slice(&b[b_len - 4..]);
Ok(PhyPayload {
mhdr,
payload: Payload::from_slice(m_type, &b[1..b_len - 4])?,
payload: Payload::from_slice(f_type, &b[1..b_len - 4])?,
mic: Some(mic),
})
}
@ -808,7 +808,7 @@ impl PhyPayload {
return Ok(());
}
let uplink = is_uplink(self.mhdr.m_type);
let uplink = is_uplink(self.mhdr.f_type);
// a_fcnt_down is used on downlink when f_port > 0
let a_fcnt_down = !uplink && pl.f_port.is_some() && pl.f_port.unwrap() > 0;
@ -842,7 +842,7 @@ impl PhyPayload {
/// Decode f_opts to mac-commands.
pub fn decode_f_opts_to_mac_commands(&mut self) -> Result<()> {
if let Payload::MACPayload(pl) = &mut self.payload {
let uplink = is_uplink(self.mhdr.m_type);
let uplink = is_uplink(self.mhdr.f_type);
pl.fhdr.f_opts.decode_from_raw(uplink)?;
}
Ok(())
@ -858,7 +858,7 @@ impl PhyPayload {
/// Note that this requires a decrypted frm_payload.
pub fn decode_frm_payload(&mut self) -> Result<()> {
if let Payload::MACPayload(pl) = &mut self.payload {
let uplink = is_uplink(self.mhdr.m_type);
let uplink = is_uplink(self.mhdr.f_type);
let f_port = pl.f_port.unwrap_or(0);
let b = match &pl.frm_payload {
Some(FRMPayload::Raw(v)) => v.clone(),
@ -883,7 +883,7 @@ impl PhyPayload {
return Ok(());
}
let uplink = is_uplink(self.mhdr.m_type);
let uplink = is_uplink(self.mhdr.f_type);
let data = pl.frm_payload.as_ref().unwrap().to_vec()?;
let data = encrypt_frm_payload(key, uplink, &pl.fhdr.devaddr, pl.fhdr.f_cnt, &data)?;
@ -905,7 +905,7 @@ impl PhyPayload {
return Ok(());
}
let uplink = is_uplink(self.mhdr.m_type);
let uplink = is_uplink(self.mhdr.f_type);
let data = pl.frm_payload.as_ref().unwrap().to_vec()?;
let data = encrypt_frm_payload(key, uplink, &pl.fhdr.devaddr, pl.fhdr.f_cnt, &data)?;
@ -1210,14 +1210,14 @@ pub fn encrypt_frm_payload(
Ok(data[0..data_len].to_vec())
}
fn is_uplink(m_type: MType) -> bool {
match m_type {
MType::JoinRequest
| MType::UnconfirmedDataUp
| MType::ConfirmedDataUp
| MType::RejoinRequest => true,
MType::JoinAccept | MType::UnconfirmedDataDown | MType::ConfirmedDataDown => false,
MType::Proprietary => false,
fn is_uplink(f_type: FType) -> bool {
match f_type {
FType::JoinRequest
| FType::UnconfirmedDataUp
| FType::ConfirmedDataUp
| FType::RejoinRequest => true,
FType::JoinAccept | FType::UnconfirmedDataDown | FType::ConfirmedDataDown => false,
FType::Proprietary => false,
}
}
@ -1261,7 +1261,7 @@ mod tests {
PhyPayloadTest {
phy: PhyPayload {
mhdr: MHDR {
m_type: MType::Proprietary,
f_type: FType::Proprietary,
major: Major::LoRaWANR1,
},
payload: Payload::Raw(vec![]),
@ -1272,7 +1272,7 @@ mod tests {
PhyPayloadTest {
phy: PhyPayload {
mhdr: MHDR {
m_type: MType::Proprietary,
f_type: FType::Proprietary,
major: Major::LoRaWANR1,
},
payload: Payload::Raw(vec![0x01, 0x02, 0x03]),
@ -1294,7 +1294,7 @@ mod tests {
let tests = vec![PhyPayloadTest {
phy: PhyPayload {
mhdr: MHDR {
m_type: MType::JoinRequest,
f_type: FType::JoinRequest,
major: Major::LoRaWANR1,
},
payload: Payload::JoinRequest(JoinRequestPayload {

Some files were not shown because too many files have changed in this diff Show More